Python では、リストを別のリストに割り当てると、次のようになります。
a = [1,2,3]
b = a
これで b と a は同じリストを指します。ここで、2 つのリストを考えます。
a = [1,2,3]
b = [4,5,6]
a,b = b,a
では、それらが他のデータ型と同じように交換され、両方が同じリストを指していないのはなぜでしょうか?
Python では、リストを別のリストに割り当てると、次のようになります。
a = [1,2,3]
b = a
これで b と a は同じリストを指します。ここで、2 つのリストを考えます。
a = [1,2,3]
b = [4,5,6]
a,b = b,a
では、それらが他のデータ型と同じように交換され、両方が同じリストを指していないのはなぜでしょうか?
Python が内部的に項目を交換しているようです。このプログラムをチェック
a, b = [1, 2], [2, 3]
def func():
a, b = b, a
import dis
dis.dis(func)
出力
4 0 LOAD_FAST 0 (b)
3 LOAD_FAST 1 (a)
6 ROT_TWO
7 STORE_FAST 1 (a)
10 STORE_FAST 0 (b)
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
そのため、Pythonは を使用して参照をスタックからb
、およびa
スタックにプッシュしますLOAD_FAST
。したがって、一番上の要素は が指す参照でa
あり、次の要素は が指す参照b
です。次にROT_TWO
、スタックの上位 2 つの要素を交換するために使用します。したがって、今、一番上の要素は が指す参照でb
あり、次の要素は が指す参照であり、スタックの一番上の 2 つの要素をそれぞれa
および に割り当てます。a
b
STORE_FAST
これが、処理するアイテムの数が 4 未満の場合に、割り当てステートメントでソートが行われる方法です。
アイテムの数が 4 以上の場合、タプルを作成して値をアンパックします。このプログラムをチェック
a, b, c, d = [1, 2], [2, 3], [4, 5], [5, 6]
def func():
a, b, c, d = d, c, b, a
import dis
dis.dis(func)
出力
4 0 LOAD_FAST 0 (d)
3 LOAD_FAST 1 (c)
6 LOAD_FAST 2 (b)
9 LOAD_FAST 3 (a)
12 BUILD_TUPLE 4
15 UNPACK_SEQUENCE 4
18 STORE_FAST 3 (a)
21 STORE_FAST 2 (b)
24 STORE_FAST 1 (c)
27 STORE_FAST 0 (d)
30 LOAD_CONST 0 (None)
33 RETURN_VALUE
Python の代入は最初に右側の式を評価し、次にその結果を左側のターゲットに適用するためです。
そのため、まずPython は をタプルとして作成(<reference to list b>, <reference to list a>)
し、次にそのタプルの最初の項目を に割り当て、そのタプルa
の 2 番目の項目を に割り当てb
ます。これにより、参照がきれいに交換されます。
割り当てを展開して、次のように読むことができます。
tmp = b, a
a = tmp[0]
b = tmp[1]
では、それらが他のデータ型と同じように交換され、両方が同じリストを指していないのはなぜでしょうか?
タプルをタプルにアンパックした瞬間に、元の参照が失わb, a
れ、再割り当てされるためです。a, b
a
b