Python docは、リストをスライスすると新しいリストが返されると言っています。
「新しい」リストが返される場合、「スライスへの割り当て」に関連する次の疑問があります。
a = [1, 2, 3]
a[0:2] = [4, 5]
print a
これで、出力は次のようになります。
[4, 5, 3]
非常によく似た構文を使用する2つの異なる操作を混同しています。
1)スライス:
b = a[0:2]
これにより、a
のスライスのコピーが作成され、b
に割り当てられます。
2)スライスの割り当て:
a[0:2] = b
このは、a
のスライスをb
の内容に置き換えます。
構文は似ていますが(設計上想像してください!)、これらは2つの異なる操作です。
=
演算子の左側にa
を指定すると、Pythonの通常の割り当てが使用され、現在のコンテキストの名前a
は、新しい値を指します。これは、a
が指していた以前の値を変更しません。
a[0:2]
演算子の左側に=
を指定することで、Python使用したいスライスの割り当て。スライス割り当てはリストの特別な構文で、リストの内容を挿入、削除、または置換できます。
挿入:
>>> a = [1, 2, 3]
>>> a[0:0] = [-3, -2, -1, 0]
>>> a
[-3, -2, -1, 0, 1, 2, 3]
削除:
>>> a
[-3, -2, -1, 0, 1, 2, 3]
>>> a[2:4] = []
>>> a
[-3, -2, 1, 2, 3]
交換:
>>> a
[-3, -2, 1, 2, 3]
>>> a[:] = [1, 2, 3]
>>> a
[1, 2, 3]
注意:
スライスの長さは、割り当てられたシーケンスの長さと異なる場合があり、ターゲットシーケンスで許可されている場合は、ターゲットシーケンスの長さが変更されます。 - source
スライスの割り当ては、 Tuple Unpacking と同様の機能を提供します。たとえば、a[0:1] = [4, 5]
は次と同等です。
# Tuple Unpacking
a[0], a[1] = [4, 5]
Tuple Unpackingを使用すると、非順次リストを変更できます。
>>> a
[4, 5, 3]
>>> a[-1], a[0] = [7, 3]
>>> a
[3, 5, 7]
ただし、要素の挿入または削除はできないため、タプルのアンパックは置換に限定されます。
これらすべての操作の前後で、a
はまったく同じリストです。 Pythonは、リストをインプレースで変更するための素敵な構文糖を提供するだけです。
以前に同じ質問に出くわしましたが、それは言語仕様に関連しています。 assignment-statements によると、
割り当ての左側がサブスクリプションの場合、Pythonはそのオブジェクトで __setitem__
を呼び出します。a[i] = x
はa.__setitem__(i, x)
。
割り当ての左側がスライスの場合、Pythonも__setitem__
を呼び出しますが、異なる引数を使用します:a[1:4]=[1,2,3]
はa.__setitem__(slice(1,4,None), [1,2,3])
と同等です
これが、「=」の左側のリストスライスの動作が異なる理由です。
割り当て操作の左側でスライスすることにより、割り当てるアイテムを指定します。