
0xc0de
Ich sehe an vielen Stellen die Verwendung von Slice-Zuweisungen für list
s. Ich kann seine Verwendung verstehen, wenn er mit (nicht standardmäßigen) Indizes verwendet wird, aber ich kann seine Verwendung nicht verstehen wie:
a_list[:] = ['foo', 'bar']
Wie unterscheidet sich das von
a_list = ['foo', 'bar']
?

agf
a_list = ['foo', 'bar']
Erstellt ein neues list
in Erinnerung und zeigt den Namen a_list
daran. Es ist unerheblich was a_list
vorher hingewiesen.
a_list[:] = ['foo', 'bar']
Ruft die an __setitem__
Methode der a_list
Objekt mit a slice
als Index und eine neue list
als Wert im Speicher angelegt.
__setitem__
wertet die slice
um herauszufinden, welche Indizes es darstellt, und ruft auf iter
auf den Wert, der übergeben wurde. Anschließend wird das Objekt durchlaufen, wobei jeder Index innerhalb des durch die angegebenen Bereichs festgelegt wird slice
zum nächsten Wert aus dem Objekt. Zum list
s, wenn der von der angegebene Bereich slice
hat nicht die gleiche Länge wie das Iterable, das list
wird verkleinert. Dadurch können Sie eine Reihe interessanter Dinge tun, z. B. Abschnitte einer Liste löschen:
a_list[:] = [] # deletes all the items in the list, equivalent to 'del a_list[:]'
oder Einfügen neuer Werte in die Mitte einer Liste:
a_list[1:1] = [1, 2, 3] # inserts the new values at index 1 in the list
Allerdings mit “erweiterten Slices”, wo die step
nicht eins ist, muss das Iterable die richtige Länge haben:
>>> 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
Die wichtigsten Dinge, die sich bei der Slice-Zuweisung unterscheiden a_list
sind:
a_list
muss bereits auf ein Objekt zeigen
- Dieses Objekt wird modifiziert, anstatt darauf zu zeigen
a_list
an einem neuen Objekt
- Dieses Objekt muss unterstützen
__setitem__
mit einer slice
Index
- Das Objekt auf der rechten Seite muss die Iteration unterstützen
- Auf das Objekt auf der rechten Seite wird kein Name gezeigt. Wenn es keine anderen Verweise darauf gibt (z. B. wenn es sich wie in Ihrem Beispiel um ein Literal handelt), wird es nach Abschluss der Iteration als Verweis nicht mehr existierend gezählt.

Jochen Ritzel
Der Unterschied ist ziemlich groß! Im
a_list[:] = ['foo', 'bar']
Sie ändern eine vorhandene Liste, die an den Namen gebunden war a_list
. Auf der anderen Seite,
a_list = ['foo', 'bar']
weist dem Namen eine neue Liste zu a_list
.
Vielleicht hilft das:
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
Durch die Zuordnung zu a_list[:]
, a_list
immer noch Verweis auf dasselbe Listenobjekt, mit geändertem Inhalt. Durch die Zuordnung zu a_list
, a_list
jetzt Verweis auf ein neues Listenobjekt.
Schauen Sie sich seine an id
:
>>> a_list = []
>>> id(a_list)
32092040
>>> a_list[:] = ['foo', 'bar']
>>> id(a_list)
32092040
>>> a_list = ['foo', 'bar']
>>> id(a_list)
35465096
Wie Sie sehen können, ist es id
ändert sich nicht mit der Slice-Zuweisungsversion.
Der Unterschied zwischen den beiden kann zu einem ganz anderen Ergebnis führen, beispielsweise wenn die Liste ein Parameter der Funktion ist:
def foo(a_list):
a_list[:] = ['foo', 'bar']
a = ['original']
foo(a)
print(a)
Mit diesem, a
wird ebenfalls modifiziert, aber wenn a_list = ['foo', 'bar']
wurden stattdessen verwendet, a
behält seinen ursprünglichen Wert.

Benutzer11817711
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)
10176700cookie-checkWas ist der Unterschied zwischen der Slice-Zuweisung, die die gesamte Liste aufteilt, und der direkten Zuweisung?yes