plotten - python subplot




Was passiert hinter den Kulissen, wenn Python kleine Ints hinzufügt? (2)

Diese Frage hat hier bereits eine Antwort:

Ich habe vor kurzem mit id herumgespielt und festgestellt, dass (c?) Python etwas ganz Sinnvolles tut: Es stellt sicher, dass kleine Ints immer die gleiche id .

>>> a, b, c, d, e = 1, 2, 3, 4, 5
>>> f, g, h, i, j = 1, 2, 3, 4, 5
>>> [id(x) == id(y) for x, y in zip([a, b, c, d, e], [f, g, h, i, j])]
[True, True, True, True, True]

Aber dann kam es mir in den Sinn, mich zu fragen, ob das Gleiche für die Ergebnisse mathematischer Operationen gilt. Es stellt sich heraus:

>>> nines = [(x + y, 9) for x, y in enumerate(reversed(range(10)))]
>>> [id(x) == id(y) for x, y in nines]
[True, True, True, True, True, True, True, True, True, True]

Scheint so, als ob es bei n = 257 versagt ...

>>> a, b = 200 + 56, 256
>>> id(a) == id(b)
True
>>> a, b = 200 + 57, 257
>>> id(a) == id(b)
False

Aber manchmal funktioniert es auch mit größeren Zahlen:

>>> [id(2 * x + y) == id(300 + x) for x, y in enumerate(reversed(range(301)))][:10]
[True, True, True, True, True, True, True, True, True, True]

Was ist denn hier los? Wie macht Python das?


AFAIK, id hat nichts mit der Größe des Parameters zu tun. Es MUSS einen lebenslangen eindeutigen Bezeichner zurückgeben, und es kann dasselbe Ergebnis für zwei verschiedene Parameter zurückgeben, wenn sie nicht gleichzeitig existieren.


Du bist in eine nicht ungewöhnliche Falle geraten:

id(2 * x + y) == id(300 + x)

Die beiden Ausdrücke 2 * x + y und 300 + x haben keine überlappenden Lebensdauern. Das bedeutet, dass Python die linke Seite berechnen, seine ID nehmen und dann die Ganzzahl freigeben kann, bevor es die rechte Seite berechnet. Wenn CPython eine Ganzzahl freigibt, wird sie in eine Liste von freigegebenen ganzen Zahlen eingefügt und dann wieder für eine andere Ganzzahl verwendet, wenn sie das nächste Mal benötigt. Ihre IDs stimmen also überein, auch wenn das Ergebnis der Berechnungen sehr unterschiedlich ist:

>>> x, y = 100, 40000
>>> id(2 * x + y) == id(300 + x)
True
>>> 2 * x + y, 300 + x
(40200, 400)




cpython