私は多くの場所でlist
sのスライス割り当ての使用を目にします。(デフォルト以外の)インデックスで使用した場合の使用法は理解できますが、次のように使用法を理解することはできません。
a_list[:] = ['foo', 'bar']
それはどう違うのですか
a_list = ['foo', 'bar']
?
私は多くの場所でlist
sのスライス割り当ての使用を目にします。(デフォルト以外の)インデックスで使用した場合の使用法は理解できますが、次のように使用法を理解することはできません。
a_list[:] = ['foo', 'bar']
それはどう違うのですか
a_list = ['foo', 'bar']
?
a_list = ['foo', 'bar']
メモリ内に新しいものを作成し、list
その名前をポイントしa_list
ます。a_list
前に指摘したことは関係ありません。
a_list[:] = ['foo', 'bar']
インデックスとしてaを使用し、値としてメモリ内に作成されたnewを使用して、オブジェクトの__setitem__
メソッドを呼び出します。a_list
slice
list
__setitem__
を評価して、slice
それが表すインデックスを把握し、iter
渡された値を呼び出します。次に、オブジェクトを繰り返し処理し、で指定された範囲内の各インデックスをslice
オブジェクトの次の値に設定します。list
sの場合、で指定された範囲がslice
iterableと同じ長さでない場合、list
はサイズ変更されます。これにより、リストのセクションを削除するなど、いくつかの興味深いことができます。
a_list[:] = [] # deletes all the items in the list, equivalent to 'del a_list[:]'
または、リストの途中に新しい値を挿入します。
a_list[1:1] = [1, 2, 3] # inserts the new values at index 1 in the list
ただし、が1ではない「拡張スライス」ではstep
、iterableは正しい長さである必要があります。
>>> lst = [1, 2, 3]
>>> lst[::2] = []
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
ValueError: attempt to assign sequence of size 0 to extended slice of size 2
スライスの割り当てに関して異なる主な点は次のa_list
とおりです。
a_list
すでにオブジェクトを指している必要がありますa_list
新しいオブジェクトを指す代わりに、そのオブジェクトが変更されます__setitem__
する必要がありますslice
違いはかなり大きいです!の
a_list[:] = ['foo', 'bar']
名前にバインドされていた既存のリストを変更しますa_list
。一方で、
a_list = ['foo', 'bar']
名前に新しいリストを割り当てa_list
ます。
多分これは役立つでしょう:
a = a_list = ['foo', 'bar'] # another name for the same list
a_list = ['x', 'y'] # reassigns the name a_list
print a # still the original list
a = a_list = ['foo', 'bar']
a_list[:] = ['x', 'y'] # changes the existing list bound to a
print a # a changed too since you changed the object
に割り当てることによりa_list[:]
、a_list
内容が変更された同じリストオブジェクトを引き続き参照します。に割り当てることによりa_list
、a_list
新しいリストオブジェクトを参照します。
そのをチェックしてくださいid
:
>>> a_list = []
>>> id(a_list)
32092040
>>> a_list[:] = ['foo', 'bar']
>>> id(a_list)
32092040
>>> a_list = ['foo', 'bar']
>>> id(a_list)
35465096
ご覧のとおりid
、スライス割り当てバージョンによって変更されません。
2つの間の違いは、たとえば、リストが関数のパラメーターである場合、まったく異なる結果になる可能性があります。
def foo(a_list):
a_list[:] = ['foo', 'bar']
a = ['original']
foo(a)
print(a)
これにより、a
も変更されますが、 a_list = ['foo', 'bar']
代わりに使用された場合はa
、元の値のままになります。
a_list = ['foo', 'bar']
a=a_list[:] # by this you get an exact copy of a_list
print(a)
a=[1,2,3] # even if you modify a it will not affect a_list
print(a)
print(a_list)