Порівняйте, якщо дві змінні посилаються на один і той же об’єкт у python


94

Як перевірити, чи посилаються дві змінні на один і той же об’єкт?

x = ['a', 'b', 'c']
y = x                 # x and y reference the same object
z = ['a', 'b', 'c']   # x and z reference different objects

Відповіді:


133

Ось для чого is: x is yповертається, Trueякщо xі yє однаковим об’єктом.


6
У прикладі x is zповертає False. Але якщо x та z замість списків (наприклад x, z = 13, 13) присвоюються однакові значення, тоді x is zповертається True. Чому так?
Білл

12
@Bill: Це артефакт того, як python обробляє ints. Python виділяє цілочисельні об'єкти, до яких xі zвказує. Оскільки малі цілі числа є загальноприйнятими (-1 як значення помилки, 0 кожного разу, коли ви насправді щось індексуєте, малі числа, як правило, є розумними значеннями за замовчуванням), Python оптимізує за допомогою попереднього розподілу малих чисел (від -5 до 256) і повторного використання того самого цілого об'єкта. Таким чином, ваш приклад працює лише для чисел у цьому діапазоні. Спробуйте призначити щось більше, тобто 270. Для отримання додаткової інформації дивіться тут
тед

1
@AndresR Ні, це неправильно. isперевіряє, чи два імена посилаються на одне і те ж місце в пам'яті. Це не має нічого спільного з самим об’єктом. Легко мати незмінні об’єкти, такі як рядки, які рівні, але не зберігаються в одному і тому ж місці, наприклад ''a'*10000 is 'a' * 10000, False.
Jochen Ritzel

1
@JochenRitzel Ви абсолютно праві, дякую за цей коментар! Тоді я не розумію, що відбувається, "af" is "af"або () is ()... чому вони мають одне і те ж місце в пам'яті?
AndresR

2
@AndreasR Для літеральних рядків / чисел у коді компілятор перевіряє, що вони існують лише один раз, і використовує їх повторно. Спеціальні значення, такі як (), None, True, False тощо, також визначаються як одиночні. Під час виконання середовище виконання також намагається повторно використовувати невеликі числа та рядки, але врешті-решт це компроміс між швидкістю та пам'яттю, і те, що трапляється, залежить від того, як реалізовано середовище виконання Python.
Йохен Рітцель,


11

Хоча два правильних рішення x is zі id(x) == id(z)вже були опубліковані, я хочу вказати на детальну реалізацію python. Python зберігає цілі числа як об'єкти, в якості оптимізації він генерує купу малих цілих чисел на своєму початку (від -5 до 256) і спрямовує КОЖНУ змінну, що містить ціле число з малим значенням, на ці попередньо ініціалізовані об'єкти. Більше інформації

Це означає, що для цілочисельних об'єктів, ініціалізованих однаковими малими числами (від -5 до 256), перевірка, чи однакові два об'єкти, поверне true ( ON C-Pyhon , наскільки мені відомо, це деталь реалізації ), тоді як для більших числа, які повертає true, лише якщо один об'єкт ініціалізований з іншого.

> i = 13
> j = 13
> i is j
True

> a = 280
> b = 280
> a is b
False

> a = b
> a
280
> a is b
True

python3,6: a = 98765; b = 98765; a є b => Правда. Щось змінилося очевидно.
Михайло Калашников

@MikhailKalashnikov Nope. Я тестував на Python 3.6.2, це все ще існує.
nix

все ще існує на python 3.7.7
Білл Хуанг,

9

Ви також можете використовувати id (), щоб перевірити, до якого унікального об’єкта посилається кожна назва змінної.

In [1]: x1, x2 = 'foo', 'foo'

In [2]: x1 == x2
Out[2]: True

In [3]: id(x1), id(x2)
Out[3]: (4509849040, 4509849040)

In [4]: x2 = 'foobar'[0:3]

In [5]: x2
Out[5]: 'foo'

In [6]: x1 == x2
Out[6]: True

In [7]: x1 is x2
Out[7]: False

In [8]: id(x1), id(x2)
Out[8]: (4509849040, 4526514944)

Примітка @ ted про використання id тут досить актуальна.
Лев Уфімцев

2

Мені дуже подобається мати візуальний зворотний зв'язок, тому я іноді просто відкриваю http://www.pythontutor.com/visualize.html#mode=edit, щоб побачити, як виділяється пам'ять і що на що посилається.

введіть тут опис зображення

Додав цей чудовий gif, оскільки ця відповідь стосується візуалізації ..


2

Це з docs.python.org: "Кожен об’єкт має ідентичність, тип і значення. Ідентичність об’єкта ніколи не змінюється після його створення; ви можете сприймати це як адресу об’єкта в пам’яті. Оператор 'is' порівнює ідентичність двох об'єктів; функція id () повертає ціле число, що представляє його ідентичність. "

Очевидно, щоразу, коли ви змінюєте значення, об'єкт відтворюється відповідно до зміни ідентичності. Рядок x = 3, за яким слідує рядок x = 3,14, не дає помилок і дає різні тотожності, типи та значення для x.


1
Відмінний док-улов.
прості
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.