+ 作るログイン
図を読み込んでいます…
1 / 26
JS から来た人の Python ― どこから来て、なぜ動くのか / 全19章

Python 04:データの入れ物 ― list・tuple・dict・set と「名前は札」

発行
アニメモ公式
版
第1版
改訂
コマ
全26

JS の配列とオブジェクトは Python では何になるのか。list・tuple・dict・set の4つの入れ物を JS と並べ、後ろから数えるインデックス、切れ目で考えるスライス、内包表記を見たうえで、「変数は箱ではなく、オブジェクトに付ける札」という見方を図で動かして確かめます。b = a の後に b を変えると a も変わる理由、文字列では変わらない理由(変更できる/できない)、浅いコピーと深いコピー、dict のキーに list が使えない理由までを1つずつ分解します。

JS の配列とオブジェクトは、Python では何になる?

第3章では、1つずつの値(数・文字列・True・None)を扱いました。でも実際のプログラムでは、「1週間分の気温」や「都市名と気温の組」のように、いくつかの値をまとめて持ちたくなります。

JS では、まとめるときはたいてい配列([28, 31, 33])かオブジェクト({ city: "東京", temp: 31 })を使います。Python にも、見た目がそっくりなものがあります。図の左右を見比べてください。

JSPython
並べたもの配列 [28, 31, 33]list [28, 31, 33]
名前と値の組オブジェクト { city: "東京" }dict {"city": "東京"}
最後に足すtemps.push(25)temps.append(25)
数temps.lengthlen(temps)
値を読むw.temp または w["temp"]w["temp"] だけ

似ているのに、微妙に違います。とくに dict では、キーを必ず "city" のように引用符で囲み、読むときも w.temp ではなく `w["temp"]` と書きます。

この章では、Python の4つの入れ物(list・tuple・dict・set)を JS と並べて見たあと、第3章で予告した「名前は札」という見方で、JS の人も一度はつまずく「コピーしたつもりが、元まで変わった」の正体を図で確かめます。

※2026年9月時点(Python 3.13)の情報です。

  • JS から来た人の Python 04 ― データの入れ物
  • 1 / 26
  • JS の配列とオブジェクトは、Python では何になる?
  • JavaScript(Node.js)
  • Python
  • const temps = [28, 31, 33];
  • temps = [28, 31, 33]
  • const w = { city: "東京", temp: 31 };
  • w = {"city": "東京", "temp": 31}
  • temps.push(25);
  • temps.append(25)
  • console.log(temps.length, w.temp);
  • print(len(temps), w["temp"])
  • // → 4 31
  • # → 4 31
  • 配列は list、オブジェクトは dict という入れ物になる。見た目はほとんど同じ
  • でも、push が append、length が len()、w.temp が w["temp"]。小さな違いには、それぞれ理由がある
  • ひらめき
  • 形はよく似ているが、dict のキーは引用符付きで、ドット(w.temp)では読めない。

入れ物は4種類:list・tuple・dict・set

Python の標準の入れ物(コレクションとも呼びます)は、主に4つです。

入れ物書き方JS で近いもの順番変更重複
list[28, 31, 33]Arrayありできるできる
tuple(35.68, 139.76)(無い)ありできないできる
dict{"temp": 31}Object・Map入れた順を保つできるキーは重複しない
set{"晴れ", "雨"}Set無いできるしない

JS では、配列とオブジェクトの2つでだいたいのことを済ませます。Python は目的ごとに入れ物を選ぶ文化です。

こんなとき選ぶ入れ物
同じ種類の物を順番に並べたい(1週間の気温)list
決まった数の値を1組にしたい(緯度と経度)tuple
名前で値を引きたい(都市名→気温)dict
重複を消したい、「含むか」をすばやく調べたいset

4つとも、中に入れられるのはどんなオブジェクトでもかまいません。数と文字列を混ぜても、list の中に dict を入れてもかまいません(dict のキーと set の要素だけは例外で、後で見ます)。

dict は、Python 3.7 から「入れた順番を必ず保つ」ことが言語の約束になりました。JS のオブジェクトもおおむね入れた順を保つので、感覚はほぼ同じです。

  • JS から来た人の Python 04 ― データの入れ物
  • 2 / 26
  • 入れ物は4種類:list・tuple・dict・set
  • list
  • tuple
  • dict
  • set
  • [28, 31, 33]
  • (35.68, 139.76)
  • {"temp": 31}
  • {"晴れ", "雨"}
  • JS の Array
  • (近いものは無い)
  • Object / Map
  • JS の Set
  • 順番あり・変更できる
  • 順番あり・変更できない
  • キーで引く・変更できる
  • 重複なし・順番なし
  • どれも「いくつかのオブジェクトをまとめて持つ」入れ物。違いは、順番・変更・重複の扱い
  • JS では配列とオブジェクトでだいたい済ませるが、Python は目的ごとに入れ物を選ぶ
  • ひらめき
  • 並べるなら list、固定の組なら tuple、名前で引くなら dict、重複を消すなら set。

list:JS の配列とほぼ同じ

list は、JS の配列とほとんど同じ感覚で使えます。[ ] で作り、0 から数える番号で読み書きし、長さは自由に伸び縮みします。

違うのは、主にメソッドの名前です。図の表をまとめるとこうなります。

やりたいことJSPython
最後に足すa.push(25)a.append(25)
長さa.lengthlen(a)
含むかa.includes(31)31 in a
つなげる[...a, ...b] や a.concat(b)a + b
並べ替え(元の list を変える)a.sort()a.sort()
並べ替え(新しく作る)a.toSorted()sorted(a)
最後を取り出して消すa.pop()a.pop()
途中に入れるa.splice(1, 0, x)a.insert(1, x)

長さが a.length のような「持ち物」ではなく、len(a) という関数なのは、Python の設計の考え方によるものです。list にも文字列にも dict にも set にも、同じ len() が使えます。JS では配列は .length、Map は .size、オブジェクトは Object.keys(o).length とバラバラでしたが、Python は「数を知りたければ、何でも len()」で統一しています。

in も同じで、31 in temps(list)、"東京" in cities(set)、"temp" in w(dict のキー)、"晴" in "晴れ"(文字列)のように、入れ物の種類を問わず使えます。

JS の sort() は何も指定しないと文字列として並べる([10, 9, 1].sort() が [1, 10, 9] になる)という落とし穴がありますが、Python の sort() は数なら数として並べます。

  • JS から来た人の Python 04 ― データの入れ物
  • 3 / 26
  • list:JS の配列とほぼ同じ
  • やりたいこと
  • JS
  • Python
  • 最後に足す
  • a.push(25)
  • a.append(25)
  • 長さ
  • a.length
  • len(a)
  • 含むか
  • a.includes(31)
  • 31 in a
  • つなげる
  • [...a, ...b]
  • a + b
  • 並べ替え(元を変える)
  • a.sort()
  • a.sort()
  • 並べ替え(新しく作る)
  • a.toSorted()
  • sorted(a)
  • 取り出して消す
  • a.pop()
  • a.pop()
  • len() が関数なのは、str にも dict にも set にも同じ len() が使えるようにするため
  • ひらめき
  • 作り方も [ ] で同じ。メソッドの名前と、長さが len() という関数になるところが違う。

インデックスは後ろからも数えられる

list の要素には、JS と同じく 0 から始まる番号(インデックス) が付いています。temps[0] が最初の 28 です。

Python では、さらにマイナスの番号が使えます。図の下段の赤い数字のように、-1 が最後、-2 が最後から2番目です。

python
temps = [28, 31, 33, 25, 22]
temps[0]     # 28
temps[-1]    # 22(最後)
temps[-2]    # 25

JS で最後の要素を取るには temps[temps.length - 1] と書くか、比較的新しい temps.at(-1) を使います。Python では昔から temps[-1] で済みます。

もう1つの違いは、範囲の外を読んだときです。

JSPython
temps[5](要素は5つ=番号は4まで)undefinedIndexError: list index out of range

JS は無い番号を読んでも undefined を返して処理を続けます。Python は第3章で見た考え方どおり、あいまいなまま続けずに止めます。undefined がどこか遠くで悪さをしてから気づくより、読んだその場で分かったほうが原因を探しやすいからです。

インデックスは、文字列や tuple にも同じように使えます。"東京都"[-1] は "都" です。

  • JS から来た人の Python 04 ― データの入れ物
  • 4 / 26
  • インデックスは後ろからも数えられる
  • temps = [28, 31, 33, 25, 22]
  • 前から
  • 0
  • 1
  • 2
  • 3
  • 4
  • 28
  • 31
  • 33
  • 25
  • 22
  • 後ろから
  • -5
  • -4
  • -3
  • -2
  • -1
  • 書き方
  • 結果
  • JS では
  • temps[0] / temps[-1]
  • 28 / 22
  • temps[0] / temps.at(-1)
  • temps[5]
  • IndexError
  • undefined(エラーにならない)
  • ひらめき
  • 0 から数えるのは JS と同じ。さらにマイナスを付けると後ろから数える。temps[-1] が最後。

スライス:[始まり:終わり] で一部を切り出す

temps[1:3] のように、角かっこの中に : をはさんで2つの番号を書くと、list の一部を切り出した新しい list が返ってきます。これをスライスと呼びます。

「1 から 3 まで」なのに、結果は [31, 33] の2つです。3番目の 25 は入りません。終わりの番号は含まないのです。

これを覚えるコツは、図のように、番号を升ではなく「切れ目」に振ってあると考えることです。28 の左が切れ目0、28 と 31 の間が切れ目1、…と数えると、temps[1:3] は「切れ目1から切れ目3までの間」になり、中にある升はちょうど 31 と 33 です。この見方なら、temps[1:3] の長さが 3 - 1 = 2 になるのも自然です。

書き方結果意味
temps[1:3][31, 33]切れ目1から3まで
temps[:2][28, 31]始まりを省くと、先頭から
temps[3:][25, 22]終わりを省くと、最後まで
temps[-2:][25, 22]最後の2つ
temps[::2][28, 33, 22]3つ目の数は「何個おきか」
temps[::-1][22, 25, 33, 31, 28]逆順
temps[:]全部丸ごとの(浅い)コピー

JS の temps.slice(1, 3) とまったく同じ意味で、「終わりを含まない」のも同じです。Python はそれを記号で短く書けるようにしたもの、と考えてください。

スライスは新しい list を作るので、切り出した結果を変えても、元の temps は変わりません。範囲の外を指定してもエラーにはならず、ある分だけが返ります(temps[3:100] は [25, 22])。

  • JS から来た人の Python 04 ― データの入れ物
  • 5 / 26
  • スライス:[始まり:終わり] で一部を切り出す
  • temps[1:3] # → [31, 33]
  • 切れ目
  • 0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 28
  • 31
  • 33
  • 25
  • 22
  • 31
  • 33
  • 新しい list ができる(元の temps は変わらない)
  • temps[:2] → [28, 31]
  • temps[3:] → [25, 22]
  • temps[::-1] → 逆順
  • temps[:] → 丸ごとコピー
  • ひらめき
  • 番号は升ではなく「切れ目」に振ってあると考える。temps[1:3] は切れ目1から3の間。

tuple:変更できない list

tuple(タプル)は、( ) で作る、あとから中身を変えられない list です。

python
pos = (35.68, 139.76)   # 東京の緯度・経度
pos[0]                  # 35.68(読むのは list と同じ)
pos[0] = 0
# TypeError: 'tuple' object does not support item assignment

JS には、tuple にあたる入れ物はありません。配列を Object.freeze() で凍らせるのが近いですが、ふだんは使いません。

変えられない入れ物が何の役に立つのでしょうか。

使いどころ例
「組」として意味が決まっている値緯度と経度、RGB の色、(年, 月, 日)
関数から複数の値を返すreturn lat, lon(第5章)
dict のキーにする{(35.68, 139.76): "東京"}(後で見ます)
渡した先で変えられたくない変えられないので、安心して渡せる

tuple でよく使うのが、分けて受け取る書き方(アンパック)です。lat, lon = pos と書くと、1つ目が lat、2つ目が lon に入ります。JS の分割代入 const [lat, lon] = pos と同じです。first, *rest = temps と書けば、JS の const [first, ...rest] = temps と同じく、残りを list で受け取れます。

tuple を作っているのは、実は ( ) ではなくカンマです。pos = 35.68, 139.76 でも tuple になります。逆に、要素が1つの tuple は (21,) とカンマが必要です。(21) はただのかっこに入った数の 21 です。

  • JS から来た人の Python 04 ― データの入れ物
  • 6 / 26
  • tuple:変更できない list
  • JavaScript(Node.js)
  • Python
  • const pos = [35.68, 139.76];
  • pos = (35.68, 139.76)
  • const [lat, lon] = pos;
  • lat, lon = pos # 分けて受け取る
  • pos[0] = 0; // 変えられてしまう
  • pos[0] = 0
  • // Object.freeze(pos) で凍らせる
  • TypeError: 'tuple' object does not
  • support item assignment
  • one = (21,) # 1つだけなら , が要る
  • tuple は「作ったら最後まで同じ」。変わらないと分かっているので、安心して渡せ、dict のキーにもなれる
  • lat, lon = pos は JS の分割代入 const [lat, lon] = pos と同じ。( ) を書かなくても、カンマがあれば tuple
  • ひらめき
  • ( ) で作り、あとから中身を変えられない。座標のような「固定の組」に使う。

dict:キーで値を引く。JS のオブジェクトの役

dict(ディクト、辞書)は、キーと値の組を集めた入れ物です。JS のオブジェクトや Map にあたります。図の右側は、dict の中身をキーと値の表として描いたものです。

python
w = {
    "city": "東京",
    "temp": 31,
}
w["temp"]        # 31
"city" in w      # True(キーがあるか)

JS との違いは2つあります。

JS のオブジェクトPython の dict
キーの書き方{ city: "東京" }(引用符を省ける){"city": "東京"}(文字列なら引用符が要る)
読み方w.city でも w["city"] でもw["city"] だけ
キーにできるもの文字列(と Symbol)変更できないものなら何でも(数・tuple も)

Python の dict では、キーはただの値です。{city: "東京"} と書くと、Python は city という名前の変数を探しに行き、無ければ NameError になります。キーが文字列なら、必ず引用符で囲みます。

なぜ w.temp と書けないのでしょうか。JS のオブジェクトは「データの入れ物」と「メソッドを持つ物(obj.method())」の2役を兼ねています。そのため、{ toString: 1 } のようにキーとメソッドの名前がぶつかる、といった混乱が起きます。

Python はこの2役を分けました。データの入れ物は dict で w["キー"]、ドット . で名前を引くのはオブジェクトの属性(メソッドなど。第7章のクラス)です。dict のメソッド(.get()、.items() など)とデータのキーが、決してぶつかりません。

ドットで読みたいデータの形があるなら、第7章の dataclass で「天気」というクラスを作るのが Python らしいやり方です。

  • JS から来た人の Python 04 ― データの入れ物
  • 7 / 26
  • dict:キーで値を引く。JS のオブジェクトの役
  • w = {
  • キー
  • 値
  • "city": "東京",
  • "temp": 31,
  • "city"
  • "東京"
  • }
  • w["temp"] # → 31
  • "city" in w # → True
  • "temp"
  • 31
  • w.temp
  • AttributeError: 'dict' object
  • キーと値の組を、入れた順に覚えている
  • has no attribute 'temp'
  • JS のオブジェクトは「データの入れ物」と「メソッドを持つ物」を兼ねているので、w.temp で読める
  • Python は役を分けた。入れ物は dict で w["キー"]、メソッドを持つ物はクラス(第7章)で obj.名前
  • ひらめき
  • キーは引用符で囲んだ文字列(や数・tuple)。読むときは w["temp"]。w.temp とは書けない。

足すのは代入、無いキーを読むと KeyError

dict に組を足すのは、JS と同じく代入です。図の右に "rain" の行が増えました。

python
w["rain"] = 10          # 組を足す(あれば上書き)
del w["rain"]           # 組を消す(JS の delete w.rain)

無いキーを読んだときの動きが、JS と大きく違います。

JSPython
w["wind"](無いキー)undefinedKeyError: 'wind'
無ければ既定値w.wind ?? 0w.get("wind", 0)
無ければ Nonew.wind(undefined)w.get("wind")

これも list の範囲外と同じ考え方です。w["tmep"] と打ち間違えたとき、JS は黙って undefined を返し、ずっと後で NaN や表示の崩れとして現れます。Python はその場で KeyError: 'tmep' と、間違えたキーの名前付きで教えてくれます。

「無いこともある」と分かっているときは、.get(キー, 既定値) で明示して読みます。

dict を回すときは、.items() でキーと値の組を取り出すのが定番です。

python
for k, v in w.items():
    print(k, v)
# city 東京
# temp 31
# rain 10

JS の for (const [k, v] of Object.entries(w)) にあたります。for k in w: と書くと、キーだけが順に出てきます。

  • JS から来た人の Python 04 ― データの入れ物
  • 8 / 26
  • 足すのは代入、無いキーを読むと KeyError
  • w["rain"] = 10 # 組を足す
  • キー
  • 値
  • w["wind"]
  • KeyError: 'wind'
  • "city"
  • "東京"
  • w.get("wind") # → None
  • w.get("wind", 0) # → 0
  • "temp"
  • 31
  • for k, v in w.items():
  • print(k, v)
  • "rain"
  • 10
  • "wind" は無い
  • → KeyError(黙って undefined にしない)
  • 無いキーを黙って undefined にすると、打ち間違い(w["tmep"])に気づけない。だから Python は止める
  • 「無いかもしれない」と分かっているときだけ、.get(キー, 既定値) で明示して読む
  • ひらめき
  • w["rain"] = 10 で組が増える。無いキーは JS なら undefined、Python ではエラー。.get() で既定値。

set:重複しない集まり。和・積・差が記号で書ける

set(セット、集合)は、同じ値を2つ持たない入れ物です。JS の Set にあたります。

python
s = {"晴れ", "雨", "晴れ"}
print(s)        # {'晴れ', '雨'}(順番は決まっていない)
len(s)          # 2

{ } にキーと値の組ではなく値だけを並べると set になります。ただし、空の set は `set()` と書きます。{} は空の dict です(dict のほうが先に {} を使っていたため)。

JS の Set と違うのは、図のような集合の計算を記号で書けることです。

書き方意味結果(a = {東京, 大阪}、b = {大阪, 札幌})
a と b を縦棒1本でつなぐ和:どちらかにある{東京, 大阪, 札幌}
a & b積:両方にある{大阪}
a - b差:a にあって b に無い{東京}
"大阪" in a含むかTrue

和は a | b と書きます(縦棒1本)。

set の強みは in の速さです。list の in は先頭から1つずつ見比べるので、要素が多いほど遅くなります。set は、後で見るハッシュという仕組みで置き場所を直接計算するので、100万個入っていても一瞬で答えが出ます。

set には順番がありません。表示の順番は入れた順とは限らないので、順番が大事なら list を使います。重複を消してから順に並べたいときは sorted(set(temps)) のように書きます。

  • JS から来た人の Python 04 ― データの入れ物
  • 9 / 26
  • set:重複しない集まり。和・積・差が記号で書ける
  • a = {"東京", "大阪"}
  • a
  • b
  • b = {"大阪", "札幌"}
  • a | b # 和 {東京, 大阪, 札幌}
  • a & b # 積 {大阪}
  • a - b # 差 {東京}
  • 東京
  • 大阪
  • 札幌
  • "大阪" in a # True
  • 空の set は set()。{} は空の dict
  • JS の Set と同じく重複を持たない。違うのは、和(|)・積(&)・差(-)を記号で書けること
  • set には順番が無いので、表示の順番は入れた順とは限らない
  • ひらめき
  • { } に値だけを並べると set。同じ値は1つにまとまる。in の判定がとても速い。

内包表記:filter と map を1行で

JS では、配列から条件に合うものを選び(filter)、それぞれを変換する(map)とき、メソッドをつなげて書きます。

js
temps.filter(t => t >= 30).map(t => Math.round(t * 1.8 + 32))
// → [88, 91](30度以上の日を華氏に)

Python では、同じことを 内包表記(リスト内包表記、list comprehension)という1つの式で書きます。

python
[round(t * 1.8 + 32) for t in temps if t >= 30]
# → [88, 91]

図の札の番号どおり、3つの部分に分けて読みます。

部分書くものJS でいうと
① round(t * 1.8 + 32)1つずつ何を作るかmap の中身
② for t in tempsどこから1つずつ取るか元の配列
③ if t >= 30どれを残すか(省略できる)filter の中身

英語で読むと「round(t × 1.8 + 32) を、temps の中の各 t について、t が30以上なら」になり、数学の集合の書き方 {2x | x ∈ A} に似せてあります。

[ ] を { } にすると、dict や set も作れます。{c: len(c) for c in cities} は「都市名 → 文字数」の dict、{t % 10 for t in temps} は set です。

Python にも map() と filter() という関数はありますが、ふつうは内包表記のほうが読みやすいとされています。ただし、条件が2つも3つも重なって1行が長くなるなら、無理をせず for 文(第6章)で書いたほうが読みやすくなります。

  • JS から来た人の Python 04 ― データの入れ物
  • 10 / 26
  • 内包表記:filter と map を1行で
  • JS
  • temps.filter(t => t >= 30).map(t => Math.round(t * 1.8 + 32))
  • Python
  • [round(t * 1.8 + 32) for t in temps if t >= 30]
  • ① 何を作るか(map)
  • ② どこから取るか
  • ③ 条件(filter)
  • temps
  • 28
  • 31
  • 33
  • 25
  • 22
  • 88
  • 91
  • 新しい list
  • {c: len(c) for c in ["東京", "札幌市"]} # dict も作れる → {'東京': 2, '札幌市': 3}
  • {t % 10 for t in temps} # set も作れる
  • ひらめき
  • [式 for 名前 in 元 if 条件]。JS の filter と map のつなぎを、1つの式で書く。

名前は札:変数は「箱」ではない

ここからが、この章の山場です。第3章で「変数は値を入れる箱ではなく、オブジェクトに付ける名前の札」と書きました。list のような変更できる入れ物を扱うとき、この見方が本当に効いてきます。

図の舞台は、左が名前(札)、右がオブジェクト(メモリ上の実体)です。

python
a = [21, 23]

この1行で起きることは、

順番起きること
1右辺の [21, 23] を評価して、list のオブジェクトを1つ作る
2左辺の名前 a という札を、そのオブジェクトに付ける

です。

「箱」のたとえで考えると、「a という箱に [21, 23] が入っている」になります。一見同じことのようですが、次の1行 b = a で、2つのたとえは違う答えを出します。

たとえb = a の意味
箱b という別の箱を用意して、a の中身を写す(コピー)
札a が付いているのと同じ物に、b という2枚目の札を付ける

Python で実際に起きるのは、札のほうです。

  • JS から来た人の Python 04 ― データの入れ物
  • 11 / 26
  • 名前は札:変数は「箱」ではない
  • 名前(札)
  • オブジェクト(メモリ上の実体)
  • a
  • 付ける
  • [21, 23]
  • list
  • a = [21, 23]
  • 箱のたとえ:a という箱に [21, 23] が入っている
  • 札のたとえ:[21, 23] という物に a という札が付いている
  • Python は「札」のほうが正しい。次の1行で違いが出る
  • ひらめき
  • a = [21, 23] は、list のオブジェクトを1つ作り、そこに a という札を付けること。

b = a はコピーではない。札が2枚になるだけ

python
b = a

図のように、札 b は、a と同じ1つの list に付きます。list のオブジェクトは1つのままで、新しい list は作られていません。

Python の公式ドキュメントも、代入を「名前をオブジェクトに束縛する(bind)」と説明しています。= がするのは札を付けること(束縛)だけで、値のコピーは一度もしません。

確かめる方法は、第3章で見た is です。

python
a is b     # True(同じ物に付いている)

JS から来た人にとって、これは実は見慣れた動きです。JS でも、const b = a とした配列やオブジェクトは同じ物を指します。

JSPython
配列・list を代入同じ物を指す同じ物に札が付く
数・文字列を代入値がコピーされる、と説明されることが多いこれも同じ物に札が付く

違いは表の2行目です。JS の入門書は「数や文字列はコピー、オブジェクトは参照」と2通りに説明しがちですが、Python は何でも同じルール(札を付けるだけ)です。それでも数や文字列で困らないのは、後で見るように「変更できない」からです。

  • JS から来た人の Python 04 ― データの入れ物
  • 12 / 26
  • b = a はコピーではない。札が2枚になるだけ
  • 名前(札)
  • オブジェクト(メモリ上の実体)
  • a
  • [21, 23]
  • list
  • b
  • 同じ物に付ける
  • a = [21, 23]
  • b = a
  • 箱のたとえなら「b という箱に中身を写した」と思ってしまう
  • 実際は、list は1つのまま。a is b は True
  • ひらめき
  • 代入は札を付けるだけ。b = a のあと、a と b は同じ1つの list に付いた2枚の札。

b.append(25) で、a から見ても変わる

python
b.append(25)
print(a)     # [21, 23, 25]

b にしか append していないのに、a を表示すると 25 が増えています。

図を見れば当たり前です。append は、札の付いている list そのものを書き換えます。札 a も札 b も、その同じ1つの list に付いているので、どちらの札から見ても変わっています。

操作何が変わるか
b.append(25)b の札が付いている物の中身
b[0] = 99同上
b.sort()同上
del b[0]同上

これらはすべて「物を変える」操作です。同じ物に札が何枚付いていても、全員から変わって見えます。

JS でも const b = a; b.push(25) とすれば a も変わるので、ここまでは JS と同じです。大事なのは、Python ではこれを「名前は札」という1つのルールで説明しきれることです。この先の「関数に list を渡すと、中で変えたものが外にも見える」(第5章)も、「デフォルト引数に [] を書くと、呼ぶたびに増えていく」(第5章)も、すべてこの絵で説明がつきます。

  • JS から来た人の Python 04 ― データの入れ物
  • 13 / 26
  • b.append(25) で、a から見ても変わる
  • 名前(札)
  • オブジェクト(メモリ上の実体)
  • a
  • [21, 23, 25]
  • list(中身が変わった)
  • b
  • a = [21, 23]
  • b = a
  • append は list そのもの(オブジェクト)を書き換える
  • b.append(25)
  • 札 a も札 b も、その同じ1つを見ているので両方変わる
  • print(a) # [21, 23, 25]
  • これは JS の const b = a; b.push(25) とまったく同じ
  • ひらめき
  • b から list を変えると、同じ list に付いている a からも変わって見える。JS の配列と同じ。

b = [0] は札の付け替え。a は無事

では、次はどうでしょう。

python
b = [0]
print(a, b)   # [21, 23, 25] [0]

今度は a は変わりません。図のように、[0] という新しい list が作られ、札 b がそちらへ付け替えられただけだからです。元の list には札 a だけが残り、中身は何も変わっていません。

ここで、2種類の操作をはっきり分けておきます。

書いたもの起きること他の札への影響
b.append(25)、b[0] = 1、b.sort()物を変える(札はそのまま)同じ物に付いた札からも変わって見える
b = [0]、b = a + [1]札を付け替える(物はそのまま)無い

見分け方は簡単で、`名前 = …` の形(名前そのものへの代入)は付け替え、それ以外(メソッドを呼ぶ、名前[…] = … に代入する)は物を変える操作です。

b[0] = 1 は = を使っていますが、左辺が名前そのものではなく「b が付いている物の0番目」なので、物を変える操作です。

「a の値を変えたつもりが変わらない」「変えるつもりが無かったのに変わった」というバグは、たいていこの2つの取り違えです。迷ったら、札とオブジェクトの絵を描いてみてください。

  • JS から来た人の Python 04 ― データの入れ物
  • 14 / 26
  • b = [0] は札の付け替え。a は無事
  • 名前(札)
  • オブジェクト(メモリ上の実体)
  • a
  • [21, 23, 25]
  • list
  • b
  • 付け替え
  • [0]
  • a = [21, 23]
  • b = a
  • list(新しい)
  • b.append(25)
  • print(a) # [21, 23, 25]
  • b = [0]
  • 書いたもの
  • 起きること
  • print(a, b) # [21, 23, 25] [0]
  • b.append(25)・b[0] = 1
  • 物を変える(札はそのまま)
  • b = [0]
  • 札を付け替える(物はそのまま)
  • ひらめき
  • = は物を書き換えない。札を別の物へ付け替えるだけ。「変える」と「付け替える」は別の操作。

変更できるもの・できないもの

Python のオブジェクトは、中身を変更できるかどうかで2つに分かれます。

分類型中身を変える操作
変更できる(ミュータブル)list、dict、setappend、代入、del など。同じ物が変わる
変更できない(イミュータブル)int、float、str、bool、None、tuple無い。一度作ったら二度と変わらない

文字列の1文字を書き換えようとすると、エラーになります。

python
s = "晴れ"
s[0] = "曇"
# TypeError: 'str' object does not support item assignment

JS も実は同じで、文字列は変更できません(s[0] = "曇" は、厳格モードでなければ黙って無視され、厳格モードなら TypeError になります)。Python はそれをエラーで知らせてくれます。

"晴れ".upper() や "晴れ".replace("晴", "曇") のような文字列のメソッドは、元を変えずに新しい文字列を作って返します。JS の文字列のメソッドと同じです。

この区別は、前の「名前は札」と組み合わせると威力を発揮します。

札が何枚も付いていると…
変更できる物誰かが変えると、全員から変わって見える(便利だが注意が要る)
変更できない物誰にも変えられないので、何枚付いていても安全

数や文字列を代入しても「コピーのように」振る舞うのは、コピーしているからではなく、そもそも変えられないからです。

  • JS から来た人の Python 04 ― データの入れ物
  • 15 / 26
  • 変更できるもの・できないもの
  • 変更できる(mutable)
  • 変更できない(immutable)
  • list
  • dict
  • set
  • int
  • float
  • str
  • append・代入・del などで、同じ物の中身が変わる
  • bool
  • None
  • tuple
  • 札が何枚付いていても、全員から変わって見える
  • 一度作ったら中身は二度と変わらない
  • s = "晴れ"; s[0] = "曇"
  • TypeError: 'str' object does not support item assignment
  • JS も同じ:文字列や数は変更できず、配列やオブジェクトは変更できる。Python はこれを型ごとにはっきり決めている
  • ひらめき
  • list・dict・set は中身を変えられる。数・文字列・tuple は変えられない。

変更できない物を「変える」と、どうなる?

では、変更できない文字列に += を使うと何が起きるのでしょうか。

python
s = "晴れ"
t = s

ここまでは list のときと同じです。図のように、札 s と札 t が、同じ1つの str のオブジェクト "晴れ" に付いています(s is t は True)。

list のとき、b.append(25) で a まで変わりました。では、ここで

python
s += "時々雨"

とすると、t も "晴れ時々雨" になるでしょうか?

「変更できない」という性質を思い出すと、答えが予想できます。"晴れ" というオブジェクトは、誰にも書き換えられないはずです。では、s が "晴れ時々雨" になるには、何が起きればいいでしょうか。

  • JS から来た人の Python 04 ― データの入れ物
  • 16 / 26
  • 変更できない物を「変える」と、どうなる?
  • 名前(札)
  • オブジェクト(メモリ上の実体)
  • s
  • "晴れ"
  • str
  • t
  • s = "晴れ"
  • t = s
  • list なら、append すると両方の札から変わって見えた
  • では文字列に += すると?
  • ひらめき
  • s と t が同じ str に付いている。ここで s += "時々雨" とすると、t も変わる?

新しい物が作られ、札が付け替わる

答えは図のとおりです。

順番起きること
1"晴れ" と "時々雨" をつないだ、新しい str のオブジェクト "晴れ時々雨" を作る
2札 s を、その新しいオブジェクトへ付け替える

元の "晴れ" は書き換えられていないので、そこに付いたままの t は "晴れ" のままです。

python
print(s)      # 晴れ時々雨
print(t)      # 晴れ
s is t        # False

つまり、変更できない物に対する s += … は、実質的に s = s + …(新しい物を作って付け替え)になります。数でも同じで、n += 1 は「n + 1 という新しい int を作り、n を付け替える」です。

こうして、変更できない物は、札が何枚付いていても安心して配れます。関数に文字列を渡しても、関数の中で書き換えられて呼んだ側が困ることはありません。逆に、変更できる list や dict を渡すときは、「中で変えられるかもしれない」と意識しておく必要があります(第5章)。

  • JS から来た人の Python 04 ― データの入れ物
  • 17 / 26
  • 新しい物が作られ、札が付け替わる
  • 名前(札)
  • オブジェクト(メモリ上の実体)
  • s
  • 付け替え
  • "晴れ時々雨"
  • str(新しく作られた)
  • t
  • "晴れ"
  • s = "晴れ"
  • t = s
  • str(元のまま)
  • s += "時々雨"
  • print(s) # 晴れ時々雨
  • 変更できない物は、誰かに書き換えられる心配が無い
  • print(t) # 晴れ
  • だから札が何枚付いていても、安心して配れる
  • ひらめき
  • str は変更できないので、+= は「つないだ新しい str を作って、s を付け替える」になる。t は元のまま。

同じ += でも、list は物を変え、str は付け替える

ここで、JS から来た人がまず予想しない動きをまとめておきます。同じ `+=` なのに、型によって結果が違うのです。

python
x = [1]
y = x
x += [2]
print(y)      # [1, 2]  ← y も変わる

s = "晴れ"
t = s
s += "時々雨"
print(t)      # 晴れ    ← t は変わらない
list の +=str や int の +=
起きること同じ list の中身を伸ばす(extend と同じ)新しい物を作り、名前を付け替える
もう1枚の札変わって見える元のまま
x is y / s is tTrue のままFalse になる

理由は、変更できる型は += で「自分自身を変える」ように作られていて、変更できない型にはそれができないからです。

ここで覚えておきたいのは、個別の規則ではなく考え方の順番です。「その型は変更できるか?」を先に考えれば、「できるなら物が変わる(他の札にも見える)」「できないなら新しい物ができる(他の札は無事)」と、答えが自然に出てきます。

  • JS から来た人の Python 04 ― データの入れ物
  • 18 / 26
  • 同じ += でも、list は物を変え、str は付け替える
  • list の +=
  • str や int の +=
  • 例
  • x = [1]; y = x; x += [2]
  • s = "晴れ"; t = s; s += "時々雨"
  • 起きること
  • 同じ list の中身を伸ばす
  • 新しい物を作り、s を付け替える
  • もう1枚の札
  • y も [1, 2] になる
  • t は "晴れ" のまま
  • x is y / s is t
  • True(同じ物のまま)
  • False(別の物になった)
  • 覚え方:「その型は変更できるか?」を先に考える。できるなら物が変わり、できないなら新しい物ができる
  • 関数に list を渡して中で変えると、呼んだ側の list も変わるのも同じ理由(第5章)
  • ひらめき
  • += の結果は、相手が変更できる型かどうかで変わる。札の絵で考えれば迷わない。

浅いコピー:外側だけが新しくなる

札を増やすのではなく、本当に別の物が欲しいときは、コピーを頼みます。list なら a.copy()(または a[:]、list(a))です。

ところが、入れ子になった list では注意が要ります。

python
nested = [[21, 23], [18, 19]]
sh = nested.copy()
sh[0].append(99)
print(nested)     # [[21, 23, 99], [18, 19]]  ← 元も変わった!

図を見てください。nested.copy() が新しく作るのは、外側の list だけです。外側の list の0番目・1番目の升には「中の list への札」が入っていて、コピーはその札を写すだけです。だから、コピーした外側(赤い矢印)も、元の外側(灰色の矢印)も、同じ中の list を指しています。

sh[0].append(99) は、sh の0番目が指している中の list(=nested の0番目と同じ物)を変えるので、nested から見ても変わります。

このように、いちばん外側だけを作り直すコピーを浅いコピー(shallow copy)と呼びます。a.copy()、a[:]、list(a)、dict.copy() はどれも浅いコピーです。

中が数や文字列だけの list なら、浅いコピーで何の問題もありません。中身は変更できない物なので、共有していても誰にも書き換えられないからです。問題になるのは、中に変更できる物(list や dict)が入っているときだけです。

  • JS から来た人の Python 04 ― データの入れ物
  • 19 / 26
  • 浅いコピー:外側だけが新しくなる
  • nested = [[21, 23], [18, 19]]
  • 外側の list
  • sh = nested.copy()
  • [21, 23, 99]
  • sh[0].append(99)
  • nested
  • [0]
  • list
  • print(nested)
  • # [[21, 23, 99], [18, 19]]
  • [1]
  • [18, 19]
  • list
  • 外側は2つあるが、
  • 外側(コピー)
  • 中の list は1つずつしか無い。
  • sh
  • [0]
  • だから sh から中を変えると
  • nested も変わる
  • [1]
  • ひらめき
  • nested.copy() は外側の list を新しく作るが、中の list は同じ物を指したまま。

深いコピー:中の中まで新しく作る

中まで全部を別物にしたいときは、標準ライブラリの copy モジュールにある `copy.deepcopy()` を使います。

python
import copy
nested = [[21, 23], [18, 19]]
dp = copy.deepcopy(nested)
dp[0].append(99)
print(nested)     # [[21, 23], [18, 19]]  ← 無事

図の緑の矢印のように、深いコピーは外側だけでなく、中の list もたどって1つずつ作り直します。コピー側の外側は、新しく作られた中の list を指すので、どこをどう変えても元の nested には影響しません。

import copy は、Python に最初から付いてくる標準ライブラリの copy モジュールを読み込む文です。この1行で何が起きているのか(どこのファイルを読んでいるのか)は、第8章でじっくり分解します。

浅いコピー深いコピー
書き方a.copy()・a[:]・list(a)copy.deepcopy(a)
作り直す範囲いちばん外側だけ中の中まで全部
速さ速い中身が多いと遅い
向いている場面中が数や文字列だけ入れ子の list・dict を丸ごと別物にしたい
  • JS から来た人の Python 04 ― データの入れ物
  • 20 / 26
  • 深いコピー:中の中まで新しく作る
  • import copy
  • 外側の list
  • nested = [[21, 23], [18, 19]]
  • [21, 23]
  • dp = copy.deepcopy(nested)
  • nested
  • [0]
  • list
  • dp[0].append(99)
  • print(nested)
  • [1]
  • # [[21, 23], [18, 19]]
  • [18, 19]
  • list
  • 外側(コピー)
  • 中まで別物なので、
  • dp をどう変えても nested は無事
  • dp
  • [0]
  • [21, 23, 99]
  • list(コピー)
  • [1]
  • [18, 19]
  • list(コピー)
  • ひらめき
  • copy.deepcopy() は中の list まで作り直す。入れ子のデータを丸ごと別物にしたいときに使う。

コピーは必ず自分で頼む

Python の = は決してコピーをしません。コピーが要るときは、必ず自分で頼みます。

やりたいことPythonJS
同じ物に札を増やすb = aconst b = a
浅いコピー(list)a.copy()・a[:]・list(a)[...a]・a.slice()
浅いコピー(dict)d.copy()・dict(d)・{**d}{ ...d }
深いコピーcopy.deepcopy(a)structuredClone(a)

JS と考え方はまったく同じです。JS の [...a] やスプレッド { ...d } も浅いコピーで、入れ子の配列やオブジェクトは共有されます。JS で「スプレッドでコピーしたのに元が変わった」経験があれば、それとまったく同じことが Python でも起きる、と思ってください。

{**d} は、dict を中身ごと展開して新しい dict を作る書き方です。JS の { ...d } にあたります。** の意味は、第5章の関数の引数でも出てきます。

  • JS から来た人の Python 04 ― データの入れ物
  • 21 / 26
  • コピーは必ず自分で頼む
  • やりたいこと
  • Python
  • JS
  • 同じ物に札を増やす
  • b = a
  • const b = a
  • 浅いコピー(list)
  • a.copy()・a[:]・list(a)
  • [...a]・a.slice()
  • 浅いコピー(dict)
  • d.copy()・dict(d)・{**d}
  • { ...d }
  • 深いコピー
  • copy.deepcopy(a)
  • structuredClone(a)
  • JS と考え方はまったく同じ。JS でも [...a] は浅いコピーで、中の配列は共有される
  • 入れ子になっていない list や dict なら、浅いコピーで十分
  • ひらめき
  • Python の = は決してコピーしない。コピーが要るときは、浅いか深いかを選んで明示する。

dict のキーと set には、変更できない物だけ入る

dict のキーと set の要素には、変更できない物しか入れられません。list をキーにしようとすると、エラーになります。

python
{[35.68, 139.76]: "東京"}
# TypeError: unhashable type: 'list'

理由は、dict がキーを探す仕組みにあります。

順番dict がすること
1キーから hash() という関数で番号(ハッシュ値)を計算する
2その番号の置き場所に、値をしまう
3読むときも同じキーから同じ番号を計算して、その置き場所を直接見に行く

1つずつ見比べずに、番号で直接取りに行くので、dict はどれだけ大きくても一瞬で値を引けます(set の in が速いのも同じ理由です)。

ところが、もしキーが list で、あとから中身が変わったらどうなるでしょう。計算し直した番号が変わってしまい、しまった場所と違う場所を探しに行って、見つけられなくなります。それを防ぐために、Python は変更できる物(list・dict・set)をキーにすることを最初から禁止しています。エラーの unhashable(ハッシュできない)はその意味です。

座標のような「組」をキーにしたいときは、tuple を使います。

python
where = {(35.68, 139.76): "東京"}
where[(35.68, 139.76)]     # "東京"

JS のオブジェクトのキーは文字列だけなので、{[1, 2]: "x"} と書くとキーが文字列の "1,2" に変換されます。Python では tuple がそのままキーになります。

  • JS から来た人の Python 04 ― データの入れ物
  • 22 / 26
  • dict のキーと set には、変更できない物だけ入る
  • 鍵
  • キー
  • "東京" や tuple など
  • hash()
  • 番号 3
  • 値
  • 0
  • 1
  • 2
  • 3
  • 4
  • 注意
  • list をキーに
  • {[35.68, 139.76]: "東京"}
  • 後から中身が変わりうる
  • TypeError: unhashable type: 'list'
  • where = {(35.68, 139.76): "東京"} # tuple ならキーにできる → where[(35.68, 139.76)] は "東京"
  • ひらめき
  • dict はキーから計算した番号(ハッシュ)で置き場所を決める。キーが変わると見つけられなくなる。

JS と並べて:よく使う操作

入れ物まわりで、JS からの書き換えによく使う操作を並べておきます。

やりたいことJSPython
要素の数a.length・Object.keys(o).lengthlen(a)・len(d)
キーの一覧Object.keys(o)d.keys()(list(d) でも同じ中身)
キーと値を回すObject.entries(o)d.items()
2つをくっつける{ ...o1, ...o2 }縦棒1本でつなぐ、または {**d1, **d2}
無いキーを読むundefinedKeyError(.get() なら None)
範囲外の番号undefinedIndexError
分割代入const [a, b] = paira, b = pair
最後の要素a.at(-1)a[-1]
一部を切り出すa.slice(1, 3)a[1:3]
選んで変換a.filter(…).map(…)[… for x in a if …]

dict どうしを d1 | d2 のように縦棒1本でくっつける書き方は Python 3.9 から使えます。後ろの dict の値が優先されるのは、JS のスプレッドと同じです。

迷ったときは、3つだけ思い出してください。どの入れ物か(list・tuple・dict・set)、変更できるか(札の付いた物が変わるのか、新しい物ができるのか)、無いものを読んだらエラーか(Python は基本的にエラーにする)。

  • JS から来た人の Python 04 ― データの入れ物
  • 23 / 26
  • JS と並べて:よく使う操作
  • やりたいこと
  • JS
  • Python
  • 要素の数
  • a.length・Object.keys(o).length
  • len(a)・len(d)
  • キーの一覧
  • Object.keys(o)
  • d.keys()(list(d) でも同じ)
  • キーと値を回す
  • Object.entries(o)
  • d.items()
  • くっつける
  • { ...o1, ...o2 }
  • d1 | d2 または {**d1, **d2}
  • 無いキー
  • undefined
  • KeyError(.get() なら None)
  • 範囲外の番号
  • undefined
  • IndexError
  • 分割代入
  • const [a, b] = pair
  • a, b = pair
  • ひらめき
  • 迷ったら「入れ物は何か」「変更できるか」「エラーにするか」の3つを思い出す。

tenki:天気のデータを dict と list で持つ

第3章の tenki は、1日分の天気を city・temp・rain という別々の変数で持っていました。何日分もの天気を扱うなら、入れ物を使います。1日分を dict、何日分かを list にするのが定番の形です。

python
# tenki.py ― 第4章の版
forecast = [
    {"day": "月", "temp": 31, "rain": 10},
    {"day": "火", "temp": 27, "rain": 60},
    {"day": "水", "temp": 33, "rain": 0},
]
for f in forecast:
    umbrella = "傘" if f["rain"] >= 50 else "-"
    print(f"{f['day']}: {f['temp']}度 {umbrella}")

hot = [f["day"] for f in forecast if f["temp"] >= 30]
print("暑い日:", hot)
$ python3 tenki.py
月: 31度 -
火: 27度 傘
水: 33度 -
暑い日: ['月', '水']

f-string の中で f['day'] と単引用符を使っているのは、外側の " と区別するためです(Python 3.12 からは同じ引用符も使えるようになりましたが、どの版でも動く書き方にしてあります)。

この「dict の list」の形は、Web の API から返ってくる JSON と同じ形です。JSON の配列は list に、オブジェクトは dict に、null は None に、true は True にそのまま対応します。第11章で本物の天気予報を API から取ってくるとき、受け取ったデータはこの形になって出てきます。

  • JS から来た人の Python 04 ― データの入れ物
  • 24 / 26
  • tenki:天気のデータを dict と list で持つ
  • # tenki.py ― 第4章の版
  • forecast = [
  • {"day": "月", "temp": 31, "rain": 10},
  • {"day": "火", "temp": 27, "rain": 60},
  • $ python3 tenki.py
  • {"day": "水", "temp": 33, "rain": 0},
  • 月: 31度 -
  • ]
  • 火: 27度 傘
  • for f in forecast:
  • 水: 33度 -
  • umbrella = "傘" if f["rain"] >= 50 else "-"
  • 暑い日: ['月', '水']
  • print(f"{f['day']}: {f['temp']}度 {umbrella}")
  • hot = [f["day"] for f in forecast if f["temp"] >= 30]
  • JSON の配列は list、オブジェクトは dict
  • print("暑い日:", hot)
  • に対応する。第11章で本物の天気を
  • 取ってくるときに、この形で受け取る
  • ひらめき
  • 1日分を dict、何日分かを list に。API から来る JSON も、Python ではこの形になる。

よくある間違いと、出るエラー

入れ物で出るエラーは、だいたい次の6つです。どれも python3 3.13 で実際に確かめたものです。

書いたもの出るエラー・結果直し方
temps[5](番号は4まで)IndexError: list index out of rangelen() で長さを確かめる。最後なら temps[-1]
w["wind"](無いキー)KeyError: 'wind'w.get("wind", 既定値) か、"wind" in w で確かめる
w.tempAttributeError: 'dict' object has no attribute 'temp'w["temp"]
{[1, 2]: "x"}TypeError: unhashable type: 'list'tuple (1, 2) をキーにする
s[0] = "曇"(文字列)TypeError: 'str' object does not support item assignment新しい文字列を作る("曇" + s[1:])
g = [[]] * 3 の後 g[0].append(1)[[1], [1], [1]](エラーは出ない)[[] for _ in range(3)]

最後の行は、エラーが出ないぶん気づきにくい罠です。[[]] * 3 の * 3 は、中の空の list をコピーせず、同じ1つの list への参照を3つ並べます。札の絵でいえば、1つの list に3枚の札が付いている状態です。だから1つに append すると、3つとも変わって見えます。

Python の公式ドキュメントにも、この例がそのまま「新しく Python を書く人がよくはまる」と載っています。直し方は、内包表記で毎回新しい list を作ることです。内包表記の [] は1周ごとに評価されるので、3つの別々の list ができます。

  • JS から来た人の Python 04 ― データの入れ物
  • 25 / 26
  • よくある間違いと、出るエラー
  • 書いたもの
  • 出るエラー・結果
  • 直し方
  • temps[5](4までしか無い)
  • IndexError: list index out of range
  • len() で長さを確かめる
  • w["wind"](無いキー)
  • KeyError: 'wind'
  • w.get("wind", 既定値)
  • w.temp
  • AttributeError: 'dict' object …
  • w["temp"]
  • {[1, 2]: "x"}
  • TypeError: unhashable type: 'list'
  • tuple (1, 2) をキーにする
  • s[0] = "曇"(str)
  • TypeError: … does not support item …
  • 新しい文字列を作る
  • g = [[]] * 3; g[0].append(1)
  • [[1], [1], [1]](エラーは出ない)
  • [[] for _ in range(3)]
  • 最後の行:* 3 は中の list をコピーせず、同じ1つに札を3枚付ける(公式ドキュメントも「初心者がよくはまる」と注意している)
  • ひらめき
  • 入れ物のエラーは6つ覚えれば足りる。いちばん気づきにくいのは [[]] * 3 の共有。

まとめ:入れ物を選び、札で考える

この章で見たことをまとめます。

項目Python では
listJS の配列。a[-1] で後ろから、a[1:3] で切り出し(切れ目で数える。新しい list)
tuple変更できない list。lat, lon = pos で分けて受け取る。dict のキーになれる
dictキーで引く。w["temp"]。無いキーは KeyError、.get() で既定値。.items() で回す
set重複なし・順番なし。縦棒・&・- で和・積・差。空は set()
内包表記[式 for 名前 in 元 if 条件]。dict と set も作れる
名前は札= は札を付ける・付け替えるだけ。コピーはしない
変更できる/できないlist・dict・set は物が変わる。数・str・tuple は新しい物ができる
コピー必ず自分で頼む。浅い(.copy())か深い(copy.deepcopy())かを選ぶ

この章のいちばん大事な絵は、「名前(札)→ オブジェクト」の矢印でした。代入は矢印を引き直すだけ、append は矢印の先の物を変える。この2つを区別できれば、Python の変数で迷うことはほとんどなくなります。

次の第5章は関数です。関数に list を渡して中で append したら、呼んだ側の list はどうなるでしょうか。デフォルト引数に [] を書いたら、なぜ呼ぶたびに中身が増えていくのでしょうか。どちらも、この章の札の絵でそのまま説明がつきます。

  • JS から来た人の Python 04 ― データの入れ物
  • 26 / 26
  • まとめ:入れ物を選び、札で考える
  • 項目
  • Python では
  • list
  • JS の配列。a[-1] で後ろから、a[1:3] で切り出し(新しい list)
  • tuple
  • 変更できない list。lat, lon = pos で分けて受け取る
  • dict
  • キーで引く。w["temp"]。無いキーは KeyError、.get() で既定値
  • set
  • 重複なし。| & - で和・積・差
  • 内包表記
  • [式 for 名前 in 元 if 条件]。dict と set も作れる
  • 名前は札
  • = は札を付けるだけ。コピーはしない
  • 変更の可否
  • list・dict・set は変えられる。数・str・tuple は変えられない
  • ひらめき
  • 次の第5章:関数に list を渡したら?デフォルト引数に [] を書いたら?札の考え方がまた効く。

0 件のコメント

読み込み中…

権利侵害・不適切な内容の連絡: [email protected]