Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 6, 2012 19:58:16

sergey.program
От:
Зарегистрирован: 2012-01-06
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

оператор IS, сравнение данных

a = "string"
b = "string"

print(a is b) #отдаёт True
print(a == b) #отдаёт True
версия питона 3.2
вопрос таков, почему отдаёт True? ведь если сравниваем к примеру
a = ["one", 1, "three-2"]# разное
b = ["one", 1, "three-2"]# разное

def oper(a, b):
if a is b:
print(True)
else:
print(False)


oper(a, b)#отдаёт False
a = b
oper(a, b)#отдаёт True
тут вроде всё нормально пишет
с чем это может быть связано?



Офлайн

#2 Янв. 6, 2012 20:08:22

s0rg
От:
Зарегистрирован: 2011-06-05
Сообщения: 777
Репутация: +  25  -
Профиль   Отправить e-mail  

оператор IS, сравнение данных

- это конструктор списка:

In [1]: a = 'string'

In [2]: b = 'string'

In [3]: a, id(a), b, id(b)
Out[3]: ('string', 3074100736L, 'string', 3074100736L)

In [4]: a = [1]

In [5]: b = [1]

In [6]: a, id(a), b, id(b)
Out[6]: ([1], 153051884, [1], 153139276)

Офлайн

#3 Янв. 6, 2012 20:17:18

sergey.program
От:
Зарегистрирован: 2012-01-06
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

оператор IS, сравнение данных

спасибо :) увидел - понял



Офлайн

#4 Ноя. 29, 2015 17:58:23

mimo
Зарегистрирован: 2015-11-29
Сообщения: 4
Репутация: +  0  -
Профиль  

оператор IS, сравнение данных

Учусь по книге Марка Саммерфилда “Программирование на Python 3”, в ней пример:

>>> a = "many paths"
>>> b = "many paths"
>>> a is b
False
>>> a == b
True

Я задаю то же самое, но без пробела, и получаю следующее:

>>> a = "manypaths"
>>> b = "manypaths"
>>> a is b
True

Почему такие результаты получаются?

Офлайн

#5 Ноя. 29, 2015 19:24:18

old_monty
Зарегистрирован: 2015-09-27
Сообщения: 238
Репутация: +  20  -
Профиль   Отправить e-mail  

оператор IS, сравнение данных

mimo
Я задаю то же самое, но без пробела, и получаю следующее:

>>> a = “manypaths”
>>> b = “manypaths”
>>> a is b
True

Почему такие результаты получаются?
В целях повышения эффективности кода Python делает кэширование малых целых чисел и небольших строк. Хотя проверка a is b возвращает True, можно легко убедиться, что ссылки a и b указывают все же не на один и тот же объект. Если бы a и b указывали на один объект, то при изменении b на какое-либо другое значение точно такое же значение должно было бы получаться у а. Но этого не происходит:
>>> x = "hello"
>>> y = "hello"
>>> x is y
True
>>> y = "world"
>>> print(x)
hello

Чтобы точно знать, сколько ссылок указывает на данный объект, можно применять функцию getrefcount() из модуля sys:
>>> import sys
>>> sys.getrefcount("manypaths")
4
Вообще, в случае малых целых чисел и небольших строк не следует полагаться в своем коде на оператор is. Даже если вы нигде не объявляли ссылку на малое число, оно может быть в кэше, и на него могут иметься десятки и даже сотни ссылок:
>>> sys.getrefcount(2)
112

Отредактировано old_monty (Ноя. 29, 2015 19:30:18)

Офлайн

#6 Ноя. 29, 2015 20:08:23

mimo
Зарегистрирован: 2015-11-29
Сообщения: 4
Репутация: +  0  -
Профиль  

оператор IS, сравнение данных

Спасибо.

Офлайн

#7 Ноя. 30, 2015 00:23:09

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10016
Репутация: +  857  -
Профиль   Отправить e-mail  

оператор IS, сравнение данных

old_monty
Хотя проверка a is b возвращает True, можно легко убедиться, что ссылки a и b указывают все же не на один и тот же объект.
Это не так. Если is возвращает True, то они связаны с одним объектом. А кто они? Они - это имена.
То есть ты неправильно сказал, потому что не знаешь механизма связывания имён с объектами.

old_monty
Если бы a и b указывали на один объект, то при изменении b на какое-либо другое значение точно такое же значение должно было бы получаться у а. Но этого не происходит:
Ты не изменил значение строки y, а создал новую строку и привязал y к ней. И забыл проверить is снова.

А то, что ты где-то прочитал, касалось мутабельных объектов.
>>> a = [1]
>>> b = a
>>> a is b
True
>>> a
[1]
>>> b
[1]
>>> a.append(2)
>>> a
[1, 2]
>>> b
[1, 2]
>>> a is b
True
>>>


mimo
Почему такие результаты получаются?
Это зависит от интерпретатора, он может оптимизировать, а может не оптимизировать. Так что у автора книги они не оптимизировались, а у тебя оптимизируются. Поэтому строки можно сравнивать только через ==.



Отредактировано py.user.next (Ноя. 30, 2015 00:27:48)

Офлайн

#8 Ноя. 30, 2015 00:46:52

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

оператор IS, сравнение данных

я бы сказал так, оператор is сравнивает Python объекты, а не их значения. Т.е. оператор is не нужно применять в задачах когда нужно сравнить значения двух переменных.

old_monty
Хотя проверка a is b возвращает True, можно легко убедиться, что ссылки a и b указывают все же не на один и тот же объект.
Вот вам из справки по Питону:
The operators is and is not test for object identity: x is y is true if and only if x and y are the same object
Ну и py.user.next вам уже разъяснил вашу ошибку.



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#9 Ноя. 30, 2015 06:07:00

old_monty
Зарегистрирован: 2015-09-27
Сообщения: 238
Репутация: +  20  -
Профиль   Отправить e-mail  

оператор IS, сравнение данных

py.user.next, JOHN_16
Посыпал голову пеплом и ушел читать документацию.

Офлайн

#10 Дек. 3, 2015 16:53:18

mimo
Зарегистрирован: 2015-11-29
Сообщения: 4
Репутация: +  0  -
Профиль  

оператор IS, сравнение данных

Так. Мне становится ясно, что ничего не ясно. )
Цитирую Саммерфилда:
“В языке Python нет переменных как таковых - вместо них используются ссылки на объекты. …интерпретатор создает объект, а затем создает ссылку на объект.

Поскольку все переменные в языке Python фактически являются ссылками, иногда возникает необходимость определить, не ссылаются ли две или более ссылок на один и тот же объект. Оператор is - это двухместный оператор, который возвращает True, если ссылка слева указывает на тот же самый объект, что и ссылка справа.

…сравниваются ссылки на объекты, а не сами объекты. Оператор is сравнивает только адреса памяти, в которых располагаются объекты - если адреса равны, следовательно, ссылки указывают на один и тот же объект.”

Python 3.5.0 (v3.5.0:374f501f4567, Sep 13 2015, 02:27:37) [MSC v.1900 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import sys
>>> #пример из книги
>>> a = "many paths"
>>> b = "many paths"
>>> id(a), id(b)    #подсмотрено в посте №2
(56237168, 56237232)
>>> sys.getrefcount("many paths")    #совет из поста №5
2
>>> a is b
False
>>> a == b
True
>>> 
>>> #повторяю без пробела
>>> a = "manypaths"
>>> b = "manypaths"
>>> id(a), id(b)
(56236976, 56236976)
>>> sys.getrefcount("manypaths")
4
>>> a is b
True
>>> a == b
True
Интерпретатор в первом случае создал два объекта, а во втором один? Почему?
old_monty
Чтобы точно знать, сколько ссылок указывает на данный объект, можно применять функцию getrefcount() из модуля sys

Почему sys.getrefcount(“manypaths”) отдает 4?

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version