変数と代入|Pythonの最初の1行
このページはプロモーション(広告)を含みます。
Pythonの最初の1行(初級・読む20分+演習30分)
この授業のゴール
=が「等しい」ではなく「右の値を左の名前に入れる」操作だと説明できるx = x + 1のような再代入を、1行ずつ値の変化を書いて追跡できる- 意味が伝わる変数名を付け、使えない名前とその理由を挙げられる
- 代入した後に元の変数を変えても、計算済みの結果は変わらないことを確かめられる
仕事でどう使うか
税率、割引率、手数料率のような値を、式のあちこちに直接書くと、変更のたびに直し漏れが起きます。値に名前を付けて1か所に書いておけば、直すのは1行で済み、読む人にも「この数字は何か」が伝わります。
| 路線 | この授業の使いどころ |
|---|---|
| DS(データサイエンティスト) | 分析の閾値(しきいち)や対象期間を変数にまとめ、条件を変えた再分析を1行の修正で行う。レポートに「この数字は変数 rate の値」と書ける |
| ML(機械学習エンジニア) | 学習率やデータ分割の割合などのハイパーパラメータ(人が事前に決める設定値)を変数に集め、実験ごとの違いを記録する |
| DX(DX推進・AI企画) | 業務ルールの数値(割引率・手数料率)を、コードの1か所にまとめて仕様書と照合する。ルール変更の影響範囲を小さくする |
| RS(研究者) | サンプルサイズや有意水準などの設定を変数として先頭に置き、論文の記述と一致しているかを確認する |
また、代入は「値が時間とともに変わる」ことを表します。いつの時点の値かを追えるかどうかが、のちのバグ探しの力になります。
前提
次の内容を前提にします。
- コードは上から下へ順に実行される、
printで結果を表示する → コードを実行して結果を見る - 文字式と代入($x$ に $3$ を入れて計算する、$x = 3$ という等式)→ 文字式と代入
- 方程式($x + 2 = 5$ のように、等式を満たす $x$ を求める)→ 方程式と不等式
数学の「$=$」は「左右が等しい」という主張でした。この授業では、Pythonの = がそれとは別の意味を持つことを、実行して確かめます。
身近な状況:税率を式のあちこちに書いてしまった
ある店の担当者が、税込価格の計算を次のように書きました。
print(1000 * 1.1)
print(2500 * 1.1)
print(480 * 1.1)
税率が変わったとき、1.1 を3か所とも直さなければなりません。1か所直し忘れると、商品ごとに違う税率で計算した表ができあがります。しかも、1.1 を見ても、それが税率なのか、別の倍率なのかは読み取れません。
値に名前を付けると、次のようになります。
tax_rate = 0.1
print(1000 * (1 + tax_rate))
print(2500 * (1 + tax_rate))
print(480 * (1 + tax_rate))
税率の定義は tax_rate = 0.1 の1行だけです。式を読む人は (1 + tax_rate) を見て「税率を加えた倍率だ」とわかります。この「値に名前を付ける」仕組みが変数で、名前に値を結びつける操作が代入です。
直感的な説明:名前札を値に貼り付ける
変数は「値を入れる箱」と説明されることが多いですが、この教材では名前札を使って考えます。price = 1000 は、1000 という値に price という名前札を貼る操作です。
名前札には、次の性質があります。
- 札を貼るときは、値を先に用意してから貼る。右辺の式(
1000 * 0.9など)を先に計算して、できた値に札を貼る。 - 同じ名前の札を貼り替えることができる。
price = 2000を実行すると、priceの札は 1000 から外れて、2000 に貼り直される。 - 貼り替えても、すでに計算してできた別の値には影響しない。
discounted = price * 0.9で 900.0 ができたあとでpriceを貼り替えても、discountedの札は 900.0 に付いたままである。
数学の等式 $y = 0.9x$ は「$x$ が変われば $y$ も変わる」という関係の宣言でした。Pythonの代入は関係ではなく、その時点の計算結果に名前を付ける操作です。この違いが、この授業の中心です。
正確な定義:代入文と変数名のルール
代入文の書き方は 名前 = 式 です。実行の順序は決まっています。
- 右辺の式を先に計算して、値を得る。
- その値に、左辺の名前を結びつける。すでに同じ名前があれば、結びつけを置き換える(再代入)。
したがって x = x + 1 は、「現在の x の値に 1 を足した値を、x に結びつけ直す」という意味です。数学の式 $x = x + 1$ は、どんな $x$ でも成り立たない($0 = 1$ になる)矛盾した式ですが、コードでは正しい操作です。
Pythonで「左右が等しいか」を調べるには、==(等号を2つ)を使います。price == 1000 は、等しければ True(真)、違えば False(偽)という真偽の値になります(数値・文字列・真偽値 で扱います)。
| 記号 | 意味 | 例 |
|---|---|---|
= |
代入:右の値を左の名前に結びつける | price = 1000 |
== |
比較:左右が等しいかを調べて True / False を得る | price == 1000 |
変数名のルールは次のとおりです。
| 名前 | 使える? | 理由 |
|---|---|---|
price / unit_price / price2 / _tmp |
使える | 英字・数字・_ で、先頭が数字でない |
2price |
使えない | 先頭が数字 |
unit-price |
使えない | - は引き算と読まれる |
unit price |
使えない | 空白で2つの語に分かれる |
class / if / for |
使えない | Pythonが文法で使う予約語 |
Price と price |
別の名前 | 大文字と小文字は区別される |
名前の付け方の目安は、(1) 何の値か意味がわかる、(2) 単語を _ でつなぐ(unit_price)、(3) 単位や形式を区別する(円なら price_yen、パーセントで持つなら rate_pct、割合なら rate)、の3つです。割合 0.1 とパーセント 10 は別物なので、名前で区別しておくと取り違えを防げます。
段階付き例題:在庫の増減を1行ずつ追跡する
問題:商品の在庫が 100 個ある。30 個売れ、その後 50 個入荷した。各時点の在庫を求める。
ステップ1:状態を表にして予想する。代入のたびに、変数の値がどう変わるかを書きます。
| 実行した行 | 右辺の計算 | stock の値 |
|---|---|---|
stock = 100 |
100 | 100 |
stock = stock - 30 |
100 − 30 = 70 | 70 |
stock = stock + 50 |
70 + 50 = 120 | 120 |
ステップ2:コードにして実行する。
stock = 100
print('初期在庫:', stock)
stock = stock - 30 # 30個売れた
print('販売後:', stock)
stock = stock + 50 # 50個入荷した
print('入荷後:', stock)
print に、コンマ区切りで文字と値を並べると、間に空白を入れて1行に表示されます(printと入力値 で詳しく扱います)。
ステップ3:結果を読む。出力は 初期在庫: 100、販売後: 70、入荷後: 120 です。表の予想と一致しました。
ステップ4:「連動しない」ことを確かめる。在庫の金額(在庫金額 = 単価 × 個数)を計算してから、個数を変えてみます。
unit_cost = 200
stock = 100
stock_value = unit_cost * stock # この時点の計算結果: 20000
stock = 70 # 個数だけ書き換える
print(stock_value)
print(unit_cost * stock)
出力は 20000 と 14000 です。stock_value は 100 個だった時点の計算結果のままです。stock を変えたあと、最新の在庫金額が必要なら、もう一度計算する必要があります。Excelのセルは参照先が変わると自動で再計算されますが、Pythonの変数はそうなりません。
操作して理解する:入れ替えと予想
2つの変数 a と b の値を入れ替える問題で、代入の順序を確かめます。まず誤った書き方を実行して、結果を予想してください。
a = 3
b = 5
a = b # a は 5 になる。元の 3 はどこにも残っていない
b = a # b には、いま a が指している 5 が入る
print(a, b)
出力は 5 5 です。a = b を実行した時点で、3 に貼ってあった a の札が 5 に貼り替わり、3 を指す名前がなくなりました。次のように、一時的な名前(tmp)で3を保存しておけば、入れ替えができます。
a = 3
b = 5
tmp = a # 3 を一時的に保存する
a = b # a は 5
b = tmp # b は保存しておいた 3
print(a, b)
出力は 5 3 です。Pythonには a, b = b, a という書き方もあります。右辺の b, a を先にまとめて計算し、その結果を左辺の a, b に同時に結びつけるので、一時的な名前が要りません。
a = 3
b = 5
a, b = b, a
print(a, b)
次に、自分で値を変えてみてください。a = 3, b = 5 を a = 10, b = 20 に変えると、出力は 20 10 になるはずです。代入の前後で、どの名前がどの値を指しているかを、紙に図で描きながら追うと、理解が確かになります。
発展:代入は「値のコピー」とは限らない
数値や文字列のようにあとから中身を書き換えられない値(不変:immutable)では、b = a のあと a を貼り替えても b には影響しません。一方、リスト(値を複数並べて持つ型。「リストとタプル」(有料版) で扱います)は、中身を後から書き換えられる可変(mutable)な値で、挙動が異なります。
a = [1, 2]
b = a # b は、a と同じリストに名札を貼る。コピーではない
b.append(3) # 同じリストに 3 を追加する
print(a) # a と b は同じリストを指しているので [1, 2, 3]
c = a.copy() # 中身を複製した新しいリスト
c.append(4)
print(a, c)
出力は [1, 2, 3] と [1, 2, 3] [1, 2, 3, 4] です。b = a は「同じものに別の名前を付ける」だけなので、b の変更が a にも見えます。コピーが必要なときは .copy() で複製します。コピーと参照の詳しい違いは 「浅いコピーと参照」(有料版) で扱います。この現象は、pandas のデータを扱うときに「元の表を変えるつもりがなかったのに書き換わっていた」という失敗として現れます。
なお、名前の通用範囲(スコープ)、関数の中の変数、global といった話題は 「ローカル変数とスコープ」(有料版) で扱います。この授業の範囲では、「名前は値に貼る札であり、貼り替えは以前の計算結果に影響しない」ことを押さえれば十分です。
よくある失敗
失敗1:Excelのように、元の値を変えれば結果も変わると考える
誤り:discounted を計算したあとで定価を変え、discounted も更新されると期待する。
price = 1000
discounted = price * 0.9
price = 2000
print(discounted)
出力は 900.0 です。discounted は price が 1000 だった時点の計算結果で、price を変えても再計算されません。期待した 1800.0 を得るには、price = 2000 の後で、もう一度 discounted = price * 0.9 を実行します。
直し方:「値を変えたら、その値を使う計算をやり直す」順序でコードを書く。一度に再計算したいなら、計算をまとめて関数にします(「関数と引数」(有料版))。
失敗2:`=` と `==` を取り違える
誤り:「等しいか調べたい」つもりで = を書く。下のコードは、誤りを文字列に入れて文法チェックだけを行います。
price = 1000
print(price == 1000) # 比較:True
print(price == 900) # 比較:False
code = '1000 = price\n' # 誤り:数値 1000 に名前を結びつけることはできない
try:
compile(code, 'sample.py', 'exec')
except SyntaxError as e:
print(type(e).__name__, '行', e.lineno)
出力は True、False、SyntaxError 行 1 です。price == 1000 は比較で、結果が True / False になります。1000 = price は「1000という値に名前を付ける」という意味になってしまい、文法として許されません。
さらに怖いのは、文法として通る = の誤用です。price = 900 と書いて「900円か確認した」つもりになると、price が書き換わるだけで、確認は行われません。直し方:確認したいときは ==、値を設定したいときは = と、目的で使い分ける。
失敗3:名前のタイプミスと大文字小文字の違い
誤り:Price(先頭が大文字)と price を同じ名前だと思い込む。
code = 'price = 1000\nprint(Price * 0.9)\n'
try:
exec(compile(code, 'sample.py', 'exec'), {})
except Exception as e:
print(type(e).__name__, ':', e)
出力は NameError : name 'Price' is not defined です。Pythonは Price と price を別の名前として扱います。rate を rat と打ち間違えた場合も同じ NameError になります。
直し方:エラーメッセージの名前と、代入した名前を1文字ずつ見比べる。エディタの補完機能を使うと、打ち間違いを減らせます。エラーが出れば気づけますが、似た名前を2つ作ってしまった場合(rate と rate2)は、エラーが出ずに古い値を使い続けるので、名前の付け方を整理しておきます。
失敗4:組み込み関数と同じ名前を変数に使い、関数が使えなくなる
誤り:合計を表す変数に sum という名前を付ける。sum はPythonがあらかじめ持っている「合計を求める関数」の名前でもあります。
sum = 10
code = 'print(sum([1, 2, 3]))\n'
try:
exec(compile(code, 'sample.py', 'exec'), {'sum': sum})
except Exception as e:
print(type(e).__name__, ':', e)
del sum
print(sum([1, 2, 3]))
最初の出力は TypeError : 'int' object is not callable です。sum という名前札が整数 10 に貼り替わったため、sum(...) が「整数を関数として呼び出す」ことになり、エラーになります。del sum で自分の貼り付けを外すと、元の関数が使え、最後の行は 6 を表示します。
直し方:total、total_price のように具体的な名前にする。sum のほか、max、min、list、print なども上書きしないようにします。
まとめ
=は代入:右辺を先に計算し、その値に左辺の名前を結びつける。等しいかの比較は==。x = x + 1は、今の値に 1 を足した結果をxに結びつけ直す再代入。数学の等式とは意味が違う。- 計算済みの結果は、元の変数を後で変えても変わらない。最新の値が必要なら、再計算する。
- 変数名は英字・数字・
_で先頭は数字以外、予約語は不可、大文字小文字は区別される。sumなど組み込み関数名の上書きに注意する。
用語
- 変数(variable)
値に付けた名前。コードの中でその名前を書くと、結びつけられた値が使われる。
- 代入(assignment)
名前 = 式の形で、式の値を計算して名前に結びつける操作。- 再代入(reassignment)
すでにある名前に、別の値を結びつけ直すこと。以前の値は(他に名前がなければ)使えなくなる。
- 予約語(reserved word / keyword)
if、for、classのように、Pythonの文法で使われる語。変数名には使えない。
よくある質問
変数は「箱」と習いましたが、名札と何が違いますか?
ほとんどの場面で同じように考えられます。違いが出るのは、b = a のあとに a と b が同じ中身を指す場合です。リストのように中身を書き換えられる値では、片方の変更がもう片方にも見えます。この教材は、その現象を説明しやすい「名前札」で説明します。
なぜ `x = x + 1` のような式が書けるのですか? 数学では成り立たないのでは?
Pythonの = は等式の主張ではなく、右辺を計算して左辺の名前に結びつける操作だからです。数学の等式は「左右が等しい」という関係を言いますが、代入は「今の値から新しい値を作って置き換える」手順です。
変数名は日本語でも付けられますか?
Pythonは日本語の変数名も許しますが、共同作業では英語(またはローマ字)で意味のある名前を付けるのが一般的です。ツールや他の言語との連携で問題が起きにくいためです。会社やチームの命名規則があれば、それに従います。
短い名前(`a`、`x`)と長い名前のどちらがよいですか?
数式をそのまま写す小さな計算では x や a も使われますが、仕事のコードでは unit_price や tax_rate のように意味を持つ名前が読みやすいです。「3か月後の自分や他人が、名前だけで何の値かわかるか」を基準にします。
変数に入れた値が途中で変わっていないか、どう確認しますか?
疑わしい行の前後に print(変数名) を入れ、値を確かめます。この授業で行ったように、各行の後の値を表にして予想し、実際の出力と比べるのが基本です。値と一緒に型も見たいときは 数値・文字列・真偽値 の type() を使います。
変数を使うと、計算を間違える危険は増えませんか?
名前の付け間違いや再代入の順序の誤りという新しい危険は増えます。一方、数字を式のあちこちに書く場合の直し漏れは減ります。対策は、意味のある名前、計算の途中結果の確認、期待値との照合です。
確認問題
問1 次のコードを実行したときの出力はどれか。
x = 5 x = x + 1 print(x)
- ① エラーになる(x = x + 1 は成り立たない式だから)
- ② 51
- ③ 6
- ④ 5
解答と解説
正解:③
右辺の
x + 1を先に計算して 6 を得て、その値にxを結びつけ直します。代入は等式の主張ではなく操作です。
問2 次のコードの出力はどれか。
price = 1000 discounted = price * 0.9 price = 2000 print(discounted)
- ① 900.0
- ② 1800.0
- ③ 2000
- ④ エラーになる
解答と解説
正解:①
discountedはpriceが 1000 だった時点の計算結果です。後からpriceを変えても、再計算は自動では行われません。
問3 次の変数名のうち、Pythonで使えるものはどれか。
- ① class
- ② unit_price
- ③ 2nd_price
- ④ unit-price
解答と解説
正解:②
変数名は、英字・数字・_ からなり、先頭は数字以外で、予約語でない必要があります。
問4 price が 1000 のとき、print(price == 1000) は何を表示するか。
- ① 1000
- ② エラー(== は存在しない記号)
- ③ price
- ④ True
解答と解説
正解:④
== は左右が等しいかを比べる演算で、結果は真偽値 True / False です。この場合は等しいので True です。
問5 code に price = 1000 と print(Price) を入れて実行したら NameError になった。原因として最も可能性が高いものはどれか。
- ①
Priceとpriceは大文字小文字が違うので別の名前として扱われた - ② Pythonが
printを理解できなかった - ③
price = 1000の=が比較になっている - ④ 1000 が大きすぎて計算できない
解答と解説
正解:①
Pythonは大文字と小文字を区別します。Price は一度も代入していない名前なので、NameError になります。
問6 a = 1、b = 2 の状態から a = b、b = a の2行を順に実行した。a と b の値はどうなるか。
- ① a は 1、b は 1 になる
- ② a も b も 2 になる
- ③ a は 2、b は 1 になる(入れ替わる)
- ④ a は 1、b は 2 のまま
解答と解説
正解:②
a = b で a が 2 に貼り替わった時点で、元の 1 を指す名前はなくなります。続く b = a は 2 を b に入れるだけです。入れ替えには一時的な名前か a, b = b, a が必要です。
次に学ぶこと
次は 数値・文字列・真偽値 で、値の種類(型)を学びます。数値と文字列と真偽値は別の種類で、"1000" と 1000 は計算の結果が変わります。
この授業の確認問題だけでモジュールの習得とはしません。PY01 の総合テストと、別の条件の自力課題で判定します。リストなど複数の値をまとめる変数は 「リストとタプル」(有料版) で扱います。
キャリア学習:データサイエンティスト・機械学習エンジニア・DX推進・研究者を目指す人の学習アプリ。164モジュール・984授業を、ブラウザで動くSQLとPythonの演習で。基礎と各分野の最初のモジュールは無料。全部は2,980円の買い切り。
アプリを無料で開く有料版と無料版の違い