ここで何が起こっているのか誰か説明してもらえますか?Pythonint
は(参照ではなく)値によって割り当てられることを理解しています。
>>> alist = [1,2,3]
>>> a = [[0]*3]*4
>>> a[0][0] = len(alist)
>>> alist.append(1)
>>> a[1][0] = len(alist)
>>> a[0][0]a
4
>>>
表記を使用してリストを作成する*
と、同じ要素が繰り返されます。要素のコピーではなく、まったく同じオブジェクトです。
繰り返しているオブジェクトが整数などの不変である場合、気付くことはありません。
リストなどのオブジェクトが変更可能である場合、同じリストが繰り返されます。1つのリストに変更を加えると、すべてのリストに変更が加えられます。
あなたの場合、要素に変更を加え、[1]
それが要素に反映されました[0]
。
問題は、外部リストに同じ内部リスト値の複数のコピーが含まれていることです。わかり方は次のとおりです。
a = [[0]*3]*4
print(a[0] is a[1]) # prints True
ゼロの2次元リストが必要な場合は、外側の部分にリスト内包表記を使用して、個別の内側リストインスタンスを取得することをお勧めします。
a = [[0]*3 for _ in range(4)]
print(a[0] is a[1]) # prints False
a[0][0]=1
print(a[1][0]) # prints 0
これは役立つかもしれません(各行のlist
との値をダンプするだけです):a
#With some commentary
>>> alist = [1,2,3] #Created a list with 3 elements
>>> alist
[1, 2, 3]
>>> a = [[0]*3]*4 #Created a list with 3 copies of one element and then copied it 4 times
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[0][0] = len(alist) #Set the 0th element of the 0th copy to 3
>>> a #Now you can see where that value was copied
[[3, 0, 0], [3, 0, 0], [3, 0, 0], [3, 0, 0]]
#The rest is just a permutation of that first 'bug'
>>> alist.append(1)
>>> alist
[1, 2, 3, 1]
>>> a[1][0] = len(alist)
>>> a
[[4, 0, 0], [4, 0, 0], [4, 0, 0], [4, 0, 0]]
>>> a[0][0]
4
このコードについての直感的でないことは、[0]*3
期待したことを実行しているように見えるかもしれませんが、そうではありませ[[0]*3]*4
んでした。このため、私は(Pythonの第一人者ではなく)intの単一の長さのリストが直感的に見える方法で処理されたと推測できますが、リストのリストはコピーアプローチにフォールバックしました。
問題ない。[[0]*3]*4
3つの要素のリストの4つのコピーでリストを作成しました。a [0]、a [1]、a [2]、およびa[3]はすべて同じリストを指します。
>>> a=[[0]*3]*4
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[0][0]='hello'
>>> a
[['hello', 0, 0], ['hello', 0, 0], ['hello', 0, 0], ['hello', 0, 0]]
>>> for mylist in a:
... print id(a)
...
42701168
42701168
42701168
42701168
>>>