25

私は多くの場所でlistsのスライス割り当ての使用を目にします。(デフォルト以外の)インデックスで使用した場合の使用法は理解できますが、次のように使用法を理解することはできません。

a_list[:] = ['foo', 'bar']

それはどう違うのですか

a_list = ['foo', 'bar']

4

4 に答える 4

33
a_list = ['foo', 'bar']

メモリ内に新しいものを作成し、listその名前をポイントしa_listます。a_list前に指摘したことは関係ありません。

a_list[:] = ['foo', 'bar']

インデックスとしてaを使用し、値としてメモリ内に作成されたnewを使用して、オブジェクトの__setitem__メソッドを呼び出します。a_listslicelist

__setitem__を評価して、sliceそれが表すインデックスを把握し、iter渡された値を呼び出します。次に、オブジェクトを繰り返し処理し、で指定された範囲内の各インデックスをsliceオブジェクトの次の値に設定します。listsの場合、で指定された範囲がsliceiterableと同じ長さでない場合、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とおりです。

  1. a_listすでにオブジェクトを指している必要があります
  2. a_list新しいオブジェクトを指す代わりに、そのオブジェクトが変更されます
  3. そのオブジェクトはインデックスでサポート__setitem__する必要がありますslice
  4. 右側のオブジェクトは反復をサポートする必要があります
  5. 右側のオブジェクトには名前が示されていません。他に参照がない場合(例のようにリテラルである場合など)、反復が完了した後、参照は存在しなくなったと見なされます。
于 2012-04-14T18:02:33.183 に答える
14

違いはかなり大きいです!の

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
于 2012-04-14T18:04:32.833 に答える
3

に割り当てることによりa_list[:]a_list内容が変更された同じリストオブジェクトを引き続き参照します。に割り当てることによりa_lista_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、元の値のままになります。

于 2015-08-09T07:33:03.067 に答える
0
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)
于 2019-07-22T07:19:36.823 に答える