it-swarm.com.de

Python mehrere Variablen demselben Wert zuweisen? List behaviour

Ich habe versucht, eine Mehrfachzuweisung wie unten gezeigt zu verwenden, um Variablen zu initialisieren, aber das Verhalten hat mich verwirrt. Ich erwarte, die Werteliste separat neu zuzuweisen. Ich meine, dass b [0] und c [0] wie zuvor gleich 0 sind.

a=b=c=[0,3,5]
a[0]=1
print(a)
print(b)
print(c)

Ergebnis ist: [1, 3, 5] [1, 3, 5] [1, 3, 5]

Ist das korrekt? Was soll ich für Mehrfachzuweisungen verwenden? Was ist anders als das?

d=e=f=3
e=4
print('f:',f)
print('e:',e)

ergebnis: ('f:', 3) ('e:', 4)

106
Marco

Wenn Sie Python aus einer Sprache der C/Java/etc. - Familie kommen, kann es hilfreich sein, a nicht mehr als "Variable" zu betrachten Fange an, es als einen "Namen" zu betrachten.

a, b und c sind keine unterschiedlichen Variablen mit gleichen Werten. Sie sind verschiedene Namen für den gleichen identischen Wert. Variablen haben Typen, Identitäten, Adressen und ähnliches.

Namen haben nichts davon. Werte natürlich, und Sie können viele Namen für den gleichen Wert haben.

Wenn Sie Notorious B.I.G. Einen Hot Dog geben, haben * Biggie Smalls Und Chris Wallace Einen Hot Dog. Wenn Sie das erste Element von a in 1 ändern, sind die ersten Elemente von b und c 1.

Wenn Sie wissen möchten, ob zwei Namen dasselbe Objekt benennen, verwenden Sie den Operator is:

>>> a=b=c=[0,3,5]
>>> a is b
True

Sie fragen dann:

was ist anders als das?

d=e=f=3
e=4
print('f:',f)
print('e:',e)

Hier binden Sie den Namen e erneut an den Wert 4. Die Namen d und f sind davon in keiner Weise betroffen.

In Ihrer vorherigen Version haben Sie a[0] Und nicht a zugewiesen. Aus Sicht von a[0] Binden Sie a[0] Erneut, aus Sicht von a ändern Sie es jedoch direkt.

Sie können die Funktion id verwenden, die Ihnen eine eindeutige Nummer gibt, die die Identität eines Objekts darstellt, um genau zu sehen, welches Objekt welches ist, auch wenn is nicht helfen kann:

>>> a=b=c=[0,3,5]
>>> id(a)
4473392520
>>> id(b)
4473392520
>>> id(a[0])
4297261120
>>> id(b[0])
4297261120

>>> a[0] = 1
>>> id(a)
4473392520
>>> id(b)
4473392520
>>> id(a[0])
4297261216
>>> id(b[0])
4297261216

Beachten Sie, dass a[0] Von 4297261120 in 4297261216 geändert wurde - es ist jetzt ein Name für einen anderen Wert. Und b[0] Ist jetzt auch ein Name für denselben neuen Wert. Das liegt daran, dass a und b immer noch dasselbe Objekt benennen.


Im Hintergrund ruft a[0]=1 Tatsächlich eine Methode für das Listenobjekt auf. (Es ist äquivalent zu a.__setitem__(0, 1).) Es ist also nicht wirklich, das überhaupt etwas neu bindet. Es ist wie der Aufruf von my_object.set_something(1). Sicher, wahrscheinlich bindet das Objekt ein Instanzattribut erneut, um diese Methode zu implementieren, aber das ist nicht wichtig. Wichtig ist, dass Sie nichts zuweisen, sondern nur das Objekt mutieren. Und so ist es auch mit a[0]=1.


user570826 hat gefragt:

Was ist, wenn wir haben, a = b = c = 10

Das ist genau die gleiche Situation wie a = b = c = [1, 2, 3]: Sie haben drei Namen für den gleichen Wert.

In diesem Fall ist der Wert ein int, und ints sind unveränderlich. In beiden Fällen können Sie a an einen anderen Wert binden (z. B. a = "Now I'm a string!"), Dies hat jedoch keine Auswirkungen auf den ursprünglichen Wert, der b und c wird noch Namen für. Der Unterschied besteht darin, dass Sie mit einer Liste den Wert [1, 2, 3] In [1, 2, 3, 4] Ändern können, indem Sie beispielsweise a.append(4); da dies tatsächlich den Wert ändert, für den b und c Namen sind, wird b jetzt b [1, 2, 3, 4]. Es gibt keine Möglichkeit, den Wert 10 In einen anderen Wert zu ändern. 10 Ist 10 für immer, genau wie Claudia, die Vampirin, 5 für immer ist (zumindest bis sie durch Kirsten Dunst ersetzt wird).


* Warnung: Geben Sie nicht Notorious B.I.G. ein Hot-Dog. Gangsta-Rap-Zombies sollten niemals nach Mitternacht gefüttert werden.

235
abarnert

Hust hust

>>> a,b,c = (1,2,3)
>>> a
1
>>> b
2
>>> c
3
>>> a,b,c = ({'test':'a'},{'test':'b'},{'test':'c'})
>>> a
{'test': 'a'}
>>> b
{'test': 'b'}
>>> c
{'test': 'c'}
>>> 
49
Jimmy Kane

Ja, das ist das erwartete Verhalten. a, b und c werden alle als Bezeichnungen für dieselbe Liste festgelegt. Wenn Sie drei verschiedene Listen möchten, müssen Sie diese einzeln zuweisen. Sie können entweder die explizite Liste wiederholen oder eine der zahlreichen Methoden zum Kopieren einer Liste verwenden:

b = a[:] # this does a shallow copy, which is good enough for this case
import copy
c = copy.deepcopy(a) # this does a deep copy, which matters if the list contains mutable objects

Zuweisungsanweisungen in Python kopieren keine Objekte - sie binden den Namen an ein Objekt, und ein Objekt kann so viele Bezeichnungen haben, wie Sie festgelegt haben. Sie aktualisieren ein Element der einzelnen Liste, auf die sich a, b und c beziehen. In der zweiten, e ändernden, ändern Sie e, um eine Bezeichnung für ein anderes Objekt zu sein (4 statt 3).

13
Peter DeGlopper

In Python ist alles ein Objekt, auch "einfache" Variablentypen (int, float usw.).

Wenn Sie einen Variablenwert ändern, ändert sich tatsächlich das Zeiger, und wenn Sie zwischen zwei Variablen vergleichen, wird das Zeiger verglichen. (Der Zeiger ist die Adresse im physischen Computerspeicher, in der eine Variable gespeichert ist.).

Wenn Sie also einen inneren Variablenwert ändern, ändert sich auch der Wert im Speicher, und alle Variablen, die auf diese Adresse verweisen, werden davon betroffen.

Für Ihr Beispiel, wenn Sie:

a = b =  5 

Dies bedeutet, dass a und b auf dieselbe Adresse im Speicher verweisen, die den Wert 5 enthält, aber wenn Sie dies tun:

a = 6

Dies hat keinen Einfluss auf b, da a jetzt auf einen anderen Speicherort mit 6 und b weiterhin auf die Speicheradresse mit 5 verweist.

Aber wenn du das tust:

a = b = [1,2,3]

a und b zeigen wieder auf dieselbe Position, aber der Unterschied besteht darin, dass Sie den einen der Listenwerte ändern:

a[0] = 2

Es ändert den Wert des Speichers, auf den a zeigt, aber a zeigt immer noch auf dieselbe Adresse wie b, und infolgedessen ändert sich auch b.

12
Ori Seri

Sie können id(name) verwenden, um zu überprüfen, ob zwei Namen dasselbe Objekt darstellen:

>>> a = b = c = [0, 3, 5]
>>> print(id(a), id(b), id(c))
46268488 46268488 46268488

Listen sind veränderlich; Dies bedeutet, dass Sie den Wert ändern können, ohne ein neues Objekt zu erstellen. Dies hängt jedoch davon ab, wie Sie den Wert ändern:

>>> a[0] = 1
>>> print(id(a), id(b), id(c))
46268488 46268488 46268488
>>> print(a, b, c)
[1, 3, 5] [1, 3, 5] [1, 3, 5]

Wenn Sie a eine neue Liste zuweisen, ändert sich deren ID, sodass die Werte von b und c davon nicht betroffen sind:

>>> a = [1, 8, 5]
>>> print(id(a), id(b), id(c))
139423880 46268488 46268488
>>> print(a, b, c)
[1, 8, 5] [1, 3, 5] [1, 3, 5]

Ganzzahlen sind unveränderlich, daher können Sie den Wert nicht ändern, ohne ein neues Objekt zu erstellen:

>>> x = y = z = 1
>>> print(id(x), id(y), id(z))
507081216 507081216 507081216
>>> x = 2
>>> print(id(x), id(y), id(z))
507081248 507081216 507081216
>>> print(x, y, z)
2 1 1
9
jurgenreza

in deinem ersten Beispiel a = b = c = [1, 2, 3] du sagst wirklich:

 'a' is the same as 'b', is the same as 'c' and they are all [1, 2, 3]

Wenn Sie "a" auf 1, "b" auf 2 und "c" auf 3 setzen möchten, versuchen Sie Folgendes:

a, b, c = [1, 2, 3]

print(a)
--> 1
print(b)
--> 2
print(c)
--> 3

Hoffe das hilft!

6
Nick Burns

Was Sie brauchen, ist das:

a, b, c = [0,3,5] # Unpack the list, now a, b, and c are ints
a = 1             # `a` did equal 0, not [0,3,5]
print(a)
print(b)
print(c)
3
pydsigner

Im ersten Fall weisen Sie einem list einfach mehrere Namen zu. Im Speicher wird nur eine Kopie der Liste erstellt, und alle Namen beziehen sich auf diesen Speicherort. Wenn Sie also die Liste mit einem der Namen ändern, wird die Liste im Speicher tatsächlich geändert.

Im zweiten Fall werden mehrere Kopien mit demselben Wert im Speicher erstellt. So ist jede Kopie unabhängig voneinander.

3
Vikas

Der Code, der das tut, was ich brauche, könnte der folgende sein:

# test

aux=[[0 for n in range(3)] for i in range(4)]
print('aux:',aux)

# initialization

a,b,c,d=[[0 for n in range(3)] for i in range(4)]

# changing values

a[0]=1
d[2]=5
print('a:',a)
print('b:',b)
print('c:',c)
print('d:',d)

Ergebnis:

('aux:', [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]])
('a:', [1, 0, 0])
('b:', [0, 0, 0])
('c:', [0, 0, 0])
('d:', [0, 0, 5])
2
Marco