
武蔵野個別指導塾の特徴
高校情報I 変数と代入—更新前後の値を分けて状態の変化を説明する|武蔵野個別指導塾

2つの容器の記録を交換し、失う値を一時変数で守る鍵は変数と代入です。
よくあるのは、2つの容器に記録した数を交換する途中で、高校生が後から必要になる値を失ってしまう場面です。左の数を右へ書き込むと、もともと右にあった数はどこに残るでしょうか。代入を1行ずつ実行し、更新前と更新後を分けて追います。
値の移動をどう問われるか
1つ目は、初期値と代入の列を受け取り、最後の値を答える型です。式を見た瞬間に変数名を置き換えるのではなく、右辺に書かれた名前がその時点で持つ値を読み、その結果を左辺に記録します。2行続けば、2行目は1行目を実行した後の状態から始まります。
2つ目は、目的に合う代入の順番を作る型です。例えば左右の記録値を入れ替える場合、最後には左が元の右、右が元の左でなければなりません。出力の順番も左、右と決めます。元の値が同じ場合は交換しても見た目が変わらないので、異なる値でも調べる必要があります。
3つ目は、間違った更新表から最初の食い違いを探す型です。最後の結果が違うときも、いきなり行を増やすのではなく、各行の直前と直後を比較します。ここで扱う容器は数を記録するための設定であり、実際に液体を移す操作ではありません。整数の記録を前提に、代入の順序を調べます。
右辺を読んでから左辺を更新する
変数は、プログラムが値に名前を付けて扱うためのものです。left = 7 は、数学の等式として左右が常に同じだと主張する文ではありません。右辺の値7を評価し、その値を名前 left に代入する命令です。その後に left = 10 と実行すると、left が表す現在の値は10になります。
left = left + 3 も同様です。右辺にある left は更新前の値を読みます。更新前が7なら右辺は10となり、評価が終わってから左辺の left が10に更新されます。右辺と左辺に同じ名前があっても、読み取る時点と書き込んだ後の時点を区別すると矛盾しません。
図1のように、代入は「現在の値を使って右辺を評価する」「評価結果を左辺へ代入する」という順で考えます。右辺の評価中に左辺の値が先に変わると考えると、更新の追跡がずれてしまいます。

図1の例では、更新前の left は7、右辺の結果は10、更新後の left は10です。右辺の 3 は加える量であり、元の値を記録する場所ではありません。表を書くときは、1つの行に実行後の値をそろえ、右辺を評価する際は直前の行を参照します。
初期化とは、後の処理で読む前に値を決めることです。まだ値を与えていない名前を右辺で読むと、Pythonでは通常 NameError になります。逆に、名前を用意しても正しい初期値を与えなければ、処理順が正しくても結果は目的に合いません。left と right は左右の記録を示し、saved は一時的に守る値を示します。名前の役割が明確なら、表の列とコードを対応させやすくなります。
基本例題: 容器の記録を交換する
左の容器の記録が4、右が9です。整数として記録された2つの値を交換し、交換後の左と右をこの順に整数で表示してください。左右の容器の記録以外に saved という一時変数を使えます。表示は空白区切りの1行です。
手で先に期待値を決めます。左には元の右の9、右には元の左の4が入るので、期待出力は 9 4 です。元の左の4を保存してから、右の9を左へ書き込み、保存した4を右へ書き込みます。図2のように、代入のたびに残る記録を確かめます。

left = 4
right = 9
saved = left
left = right
right = saved
print(left, right)
1行目と2行目は左右の記録の初期化です。3行目は現在の左の4を読み、saved に代入します。この時点で左の4も残ります。4行目は現在の右の9を読み、左を9に更新します。5行目は saved の4を読み、右を4に更新します。最後の行は左、右の順に表示します。
実行した後 left right saved
初期化後 4 9 未使用
saved = left 4 9 4
left = right 9 9 4
right = saved 9 4 4
4行目の後に9が2か所にあるのは、右の記録が左へコピーされ、右の記録自体はまだ変わらないためです。保存した4があるので、元の左の値は失われません。Python 3.14.8で入力を左4、右9として実行した出力は 9 4 でした。手で決めた期待出力に一致します。元の容器に戻して照合すると、左は元の右9、右は元の左4です。
交換の条件を広げて確かめる
同じ手順が別の整数でも成立する理由を、元の左を a、元の右を b として考えます。保存後は左が a、右が b、保存場所が a です。左を更新した後は左が b、右が b、保存場所が a です。最後に保存場所から右へ書けば、左が b、右が a となります。右の元の値は左を更新するまで残り、左の元の値は保存場所に残るためです。これは整数の具体的な値に依存しない説明です。
標準例題として、左が0、右が6のときも同じ手順を適用します。答えは左6、右0です。0は空きや未設定を意味する記号ではなく、この問題では交換する整数そのものです。保存後の saved は0、左の更新後は左6、右6、保存0です。最後に右へ0を戻すと、交換後の2つは6と0になります。Python 3.14.8で入力0、6を実行し、期待 6 0 と実際の出力 6 0 が一致しました。元の右6が左に、元の左0が右にあることも確かめられます。
発展例題では3つの記録を循環させます。左2、中央5、右8を、左には元の右、中央には元の左、右には元の中央が入るように更新し、左から順に表示してください。期待値は 8 2 5 です。2つの交換をそのまま繰り返す前に、どの値をいつ失うかを考えます。
left = 2
middle = 5
right = 8
saved = right
right = middle
middle = left
left = saved
print(left, middle, right)
最初の3行で元の記録を設定し、4行目で後から左へ渡す右の8を保存します。5行目は元の中央5を右へ、6行目は元の左2を中央へ移します。この時点で左の2は中央にも残り、元の右8は保存場所に残っています。7行目で保存した8を左へ入れ、最後の行で順に表示します。
実行した後 left middle right saved
初期化後 2 5 8 未使用
saved = right 2 5 8 8
right = middle 2 5 5 8
middle = left 2 2 5 8
left = saved 8 2 5 8
Python 3.14.8で入力2、5、8の期待 8 2 5 に対し、実際も 8 2 5 でした。元の右8は左に、元の左2は中央に、元の中央5は右にあります。これは交換を3つに増やしただけではなく、目的の向きに合わせて上書きの順番を設計した処理です。保存場所が不要になるのは最後の代入が終わった後です。
失った値を表から見つける
基本例題で次のように書くと、期待した交換にはなりません。左4、右9で実行する誤った例です。
left = 4
right = 9
left = right
right = left
print(left, right)
初期化後は左4、右9です。3行目は右の9を読み、左を9にします。この時点で元の左4は、どの変数にも記録されていません。4行目は更新後の左9を読み、右に9を代入します。Python 3.14.8で期待 9 4 に対し、実際の出力は 9 9 でした。図3のように、最初の上書きで必要な4が消えることが原因です。

図3では左側が誤った手順、右側が保存を先に行う修正です。元の左4を saved に控えてから左を9に更新し、その後 saved を右に戻します。基本例題の修正後の実行結果 9 4 は、期待値と一致します。修正前に出力だけを見ても、どちらの行で値が失われたかはわかりません。途中の状態を並べれば、最初に元の左が消えた場所を特定できます。
同じ値同士を誤った手順で交換しても、例えば両方が3なら結果は3、3です。これは誤りが見えない入力であって、異なる値の交換が正しい証拠ではありません。正しい手順にも同値を与えて、不要な変化が起きないことを確かめます。入力を与えない場合や整数以外を許す場合は、この例題の前提を満たさないため、交換結果を決めません。入力の受け取り方や例外処理を加えるなら、別に仕様を定めます。
自分で追う5問
各問の数は整数です。答えは指定された順の整数か、指定された説明で示してください。コードを読む問は、上から順に1行ずつ実行します。
- 記録
countが11のときcount = count + 4を実行します。更新後の整数を答えてください。 - 左が13、右が7です。基本例題の3つの代入で交換するとき、保存後、左の更新後、右の更新後の左・右・保存の組をそれぞれ答えてください。
- 左が6、右が6です。同じ交換手順の後の左と右を答え、同じ値の入力だけで手順を判定できない理由を述べてください。
- 左が15、右が2です。誤答の2つの代入を実行した後の左と右を答え、どの元の値が失われたか示してください。
- 左3、中央10、右12の3つを発展例題と同じ向きに循環させます。左、中央、右の順に結果を答え、各結果がどの元の位置から来たかを示してください。
答えと照合
- 15です。右辺では更新前の11に4を加えるので15となり、それを
countに代入します。実行結果も15です。元の11から4増えた記録に戻して確かめられます。 - 順に
(13, 7, 13)、(7, 7, 13)、(7, 13, 13)です。保存した13を最後に右へ渡します。実行結果の左7、右13は、それぞれ元の右7、元の左13と一致します。 - 左6、右6です。保存した6を右へ戻しても見た目は変わりません。実行結果も6、6です。誤った2行でも同じ出力になるため、異なる値を使う確認が必要です。
- 左2、右2です。最初の代入で左が2になり、元の左15が失われます。次の代入は更新後の左2を右に書くので、実行結果も2、2です。右に元の左15がないため、交換の条件を満たしません。
- 左12、中央3、右10です。保存場所に元の右12を置き、右へ元の中央10、中央へ元の左3、左へ保存した12を渡します。実行結果も12、3、10です。3つの元の記録が指定の移動先へそれぞれ届いています。
練習の計算はPython 3.14.8でも確かめました。問題1は入力11、4で期待と実際が15、問題2は入力13、7で上の3組、問題3は入力6、6で6、6、問題4は入力15、2で2、2、問題5は入力3、10、12で12、3、10でした。実行結果を手順表と照合し、それぞれの元の位置へ戻して検証しています。これらの入力で一致したことと、先ほどの記号 a、b による成立理由は別の確認です。
覚えておくこと
代入は右辺を評価してから左辺の名前を更新します。 同じ名前を右辺で読むときは更新前の値を使います。 上書き後に必要な値は、先に別の変数へ保存します。 期待値、途中の状態、実際の出力を照らし合わせます。
前提を外れた入力と実行の失敗
この交換例は、整数が2つそろっていることを前提にしています。入力を受け取る処理は含まないため、空入力、文字を整数として読めない入力、片方だけしかない入力は、このコードに渡す有効な条件ではありません。例えば空の入力で input を使う別のプログラムなら EOFError、整数への変換に文字 abc を渡せば ValueError、未定義の名前を読めば NameError になります。いずれも交換結果を推測せず、入力や初期化の不足として扱います。
今回のコードは外部の道具や通信を呼び出さず、反復もしません。そのため、外部の道具の失敗や時間切れを処理する仕組みは含まれていません。実行環境が途中で停止した場合は、表示がないことを交換成功とみなさず、初期値を確認して最初から再実行します。入力を受け取る実用のプログラムへ拡張する場合には、入力の検証、エラー表示、時間切れ時の扱いを先に決め、それぞれの失敗を実際に起こして確認します。
つまずいた場所を見分ける
更新表で右辺の値から違う場合は、直前の行を見ているかを確認します。右辺は合っているのに別の列を変えている場合は、代入先の名前を指で示し、変化する列を1つ選びます。交換後に両方が同じ値になる場合は、元の値が最後に必要になる時点まで残っているかを追います。
個別指導では、答えを先に直すより、本人に各行の直前の値と右辺の評価結果を声に出して説明してもらいます。保存の行を省いた表と加えた表を比べれば、どの値がどこで保たれたかを確認できます。代入の順を理解すると、値が変わる理由を自分の表で説明できます。
読んで終わりにするか、ここから変えるか。
武蔵境駅徒歩30秒、講師1人に生徒1人の完全1対1。授業のあいだ、先生は隣を離れません。いまの詰まりを、無料相談でそのまま話してください。
まず15分だけ電話で話したい方は、無料電話相談(15分)から。塾からお電話を差し上げます。
本気になった日が、入塾の日。
お子様の教育、迷ったら「丸投げ」してください。必ず、期待以上の結果で返します。武蔵野で育む、武蔵境で学ぶ。
電話は年中無休。365日、24時間、お電話可能。




