Як перевірити, чи посилаються дві змінні на один і той же об’єкт?
x = ['a', 'b', 'c']
y = x # x and y reference the same object
z = ['a', 'b', 'c'] # x and z reference different objects
Як перевірити, чи посилаються дві змінні на один і той же об’єкт?
x = ['a', 'b', 'c']
y = x # x and y reference the same object
z = ['a', 'b', 'c'] # x and z reference different objects
Відповіді:
Ось для чого is: x is yповертається, Trueякщо xі yє однаковим об’єктом.
x is zповертає False. Але якщо x та z замість списків (наприклад x, z = 13, 13) присвоюються однакові значення, тоді x is zповертається True. Чому так?
xі zвказує. Оскільки малі цілі числа є загальноприйнятими (-1 як значення помилки, 0 кожного разу, коли ви насправді щось індексуєте, малі числа, як правило, є розумними значеннями за замовчуванням), Python оптимізує за допомогою попереднього розподілу малих чисел (від -5 до 256) і повторного використання того самого цілого об'єкта. Таким чином, ваш приклад працює лише для чисел у цьому діапазоні. Спробуйте призначити щось більше, тобто 270. Для отримання додаткової інформації дивіться тут
isперевіряє, чи два імена посилаються на одне і те ж місце в пам'яті. Це не має нічого спільного з самим об’єктом. Легко мати незмінні об’єкти, такі як рядки, які рівні, але не зберігаються в одному і тому ж місці, наприклад ''a'*10000 is 'a' * 10000, False.
"af" is "af"або () is ()... чому вони мають одне і те ж місце в пам'яті?
y is xбуде True, y is zбуде False.
Хоча два правильних рішення 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
Ви також можете використовувати 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)
Мені дуже подобається мати візуальний зворотний зв'язок, тому я іноді просто відкриваю http://www.pythontutor.com/visualize.html#mode=edit, щоб побачити, як виділяється пам'ять і що на що посилається.
Додав цей чудовий gif, оскільки ця відповідь стосується візуалізації ..
Це з docs.python.org: "Кожен об’єкт має ідентичність, тип і значення. Ідентичність об’єкта ніколи не змінюється після його створення; ви можете сприймати це як адресу об’єкта в пам’яті. Оператор 'is' порівнює ідентичність двох об'єктів; функція id () повертає ціле число, що представляє його ідентичність. "
Очевидно, щоразу, коли ви змінюєте значення, об'єкт відтворюється відповідно до зміни ідентичності. Рядок x = 3, за яким слідує рядок x = 3,14, не дає помилок і дає різні тотожності, типи та значення для x.