実行順序を意識する
実行順序を意識する とは
コードが上から下へ実行される流れを意識して、与えられた配列を整形する関数を書こう。本レッスンでは、実行順序を意識する の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
コードは「上から順に」実行される
プログラミングを始めたばかりの人がいちばん不思議に感じることの 1 つが、コードの実行順序です。Python のプログラムは、ファイルの 上から下へ、1 行ずつ 評価されます。ここを意識せずに書くと、「あれ、この変数が定義されてない」「思った順番にならない」といったエラーや混乱が起こります。
プログラムは映画ではなく、レシピ。書いた順に手順が実行されるだけ、と考えるとシンプルです。
上から下へ、1 ステップずつ
Python インタプリタは、ファイルを読み込んで「文 (statement)」を 1 つずつ実行していきます。代入、関数呼び出し、if の判定、ループの開始、return 等が全て「文」です。
Python
x = 10 # ① x に 10 を代入
y = x * 2 # ② x を使って y を計算 (y は 20)
result = y + 5 # ③ y を使って result を計算 (result は 25)
print(result) # ④ result を表示コメント番号通りに、上から下へ評価が進みます。② の時点では x が必要なので、① で先に定義されていなければ NameError です。順番を入れ替えるだけで動かなくなる、というのが「実行順序を意識する」ということです。
コードの読みは、上から下へが基本。関数定義の中だけは「呼び出されたとき」に評価される、という例外があります。
関数の中の実行順序
関数の中も同じく、上から順に評価されます。ただし、return 文に到達した瞬間に 関数の処理は終了 します。return の下に書いた行は実行されません。
Python
def classify(n):
if n < 0:
return "negative"
if n == 0:
return "zero"
return "positive"この classify(5) の挙動は、次の流れになります。
if n < 0:を判定 →False、ブロック内はスキップif n == 0:を判定 →False、ブロック内はスキップreturn "positive"を実行 → 関数終了
return のたびに関数が終わるので、「return でフローを早期に閉じる」というスタイルは、Python 界隈で 早期 return guard clause と呼ばれ、読みやすさのために推奨されます。これは後の章でもっと深く扱います。
動きを追ってみる
配列に対して 2 段階の処理を加える流れを図示すると、次の通りです。
「ソート → 倍化」の順と、「倍化 → ソート」の順では、要素の並び順は同じになりますが、計算量が変わったり、途中の中間状態が変わったりします。やりたいことに合わせて、ステップの順序を自分で決められるようになると、プログラミングが一段楽しくなります。
副作用と再代入
実行順序を意識する上で、もう 1 つ大事なのが 副作用 という概念です。list.sort() や list.append() のように、メソッド呼び出しが 元のリストを書き換える タイプの操作は、呼んだ後に元の変数が変わっています。一方、sorted(lst) や lst + [x] のように 新しいオブジェクトを返す タイプの操作は、元の変数はそのままです。
Python
nums = [3, 1, 2]
nums.sort() # 副作用あり: nums が書き換わる
# nums は [1, 2, 3]
nums2 = [3, 1, 2]
result = sorted(nums2) # 副作用なし: nums2 は変わらない
# nums2 は [3, 1, 2], result は [1, 2, 3]どっちが「副作用あり/なし」かで挙動が全然違う。慣れるまでは
sorted()系の 新しい値を返す スタイルを優先すると、バグを減らせます。
よくある間違い
実行順序の理解不足から来る代表的なバグは、次の通りです。
- まだ代入していない変数を参照して
NameError return後の行に書いたコードが永遠に実行されないsort()を呼んだのに「副作用」だと知らず、戻り値をNoneとして扱ってしまう- ループ内で同じ変数を上書きし続け、最終値しか残っていなくて困る
特に sort() の落とし穴は、初学者の通過儀礼です。new_list = old_list.sort() と書くと、new_list には None が入って、元の old_list だけが書き換わります。「sort() は戻り値を返さず、元を書き換える」と一度刻んでしまえば二度と引っかかりません。
やってみよう
このレッスンの課題は、整数のリスト numbers を受け取り、次のステップで処理した結果を返す process 関数を書くことです。
- 元のリストを 昇順にソート
- 各要素を 2 倍
- 結果のリストを
return
書き方の一例を示します。
Python
def process(numbers):
sorted_numbers = sorted(numbers)
doubled = [n * 2 for n in sorted_numbers]
return doubledリスト内包表記 [n * 2 for n in sorted_numbers] は後の章で詳しく扱いますが、ここでは「リストの各要素を順番に処理して、新しいリストを作る書き方」と覚えておけば十分です。慣れていなければ、for ループで書いても OK です。
Python
def process(numbers):
sorted_numbers = sorted(numbers)
result = []
for n in sorted_numbers:
result.append(n * 2)
return resultどちらの書き方でも、テストはパスします。書く前に「どの順序で処理するか」を頭の中で 1 行ずつイメージしてから書くと、ミスがぐっと減ります。これがプログラミングにおける 実行順序を意識する ということです。
よくある質問
Q. このトピックは Python 以外の言語でも同じ書き方ですか?
A. 考え方は他言語と共通ですが、構文や標準ライブラリは異なります。Python はインデントでブロックを表し、コロン + 改行で構造を作るのが特徴です。他言語に移行する際は基本概念を維持しつつ、構文の差分を意識して書き換えると混乱が少ないです。
Q. 実行してエラーが出た場合の対処は?
A. エラーメッセージの最後の行(TypeError や NameError などの型)から原因と該当行を確認します。Python はトレースバックが下から上に読むと「呼び出し元 → 内部」の順で辿れます。print や IDE のデバッガで途中の変数を確認すると原因が見えてきます。
Q. 次のステップで何を学ぶべきですか?
A. 本レッスンの内容を理解できたら、本文の「やってみよう」を実装し、章末クイズに進むのがおすすめです。さらに自分のミニアプリ(電卓・todo・スコア集計など)に応用するとスキルが定着します。詰まったら本文の H2 セクションに戻って読み返してください。
次のレッスン
次は 第 1 章クイズ — はじめての Python で、コードが上から下へ実行される流れを意識して、与えられた配列を整形する関数を書こう を学びます。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- 実行順序 の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. 実行順序 とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
要件
- 関数名は process、引数はリスト numbers
- まず昇順にソートし、その後で各要素を 2 倍にする
- 新しいリストを return する
入出力例
test-cases.txt
process([3,1,2]) → [2,4,6]
process([]) → []
process([5,-1,0]) → [-2,0,10]
process([2,1,2,1]) → [2,2,4,4]