了解Python的“ is”运算符

问题:了解Python的“ is”运算符

is运营商不匹配变量的值,但这些实例本身。

到底是什么意思

我声明了两个变量,xy在两个变量中分配了相同的值,但是当我使用is运算符时,它返回false 。

我需要澄清。这是我的代码。

x = [1, 2, 3]
y = [1, 2, 3]

print(x is y)  # It prints false!

The is operator does not match the values of the variables, but the instances themselves.

What does it really mean?

I declared two variables named x and y assigning the same values in both variables, but it returns false when I use the is operator.

I need a clarification. Here is my code.

x = [1, 2, 3]
y = [1, 2, 3]

print(x is y)  # It prints false!

回答 0

您误解了is操作员的测试内容。它测试两个变量是否指向同一对象,而不是两个变量具有相同的值。

is操作员文档中:

运算符isis not对象标识测试:x is y当且仅当xy是相同对象时为true 。

改用==运算符:

print(x == y)

打印Truex并且y是两个单独的列表:

x[0] = 4
print(y)  # prints [1, 2, 3]
print(x == y)   # prints False

如果使用该id()函数,您将看到xy具有不同的标识符:

>>> id(x)
4401064560
>>> id(y)
4401098192

但是如果要分配给yx则它们都指向同一个对象:

>>> x = y
>>> id(x)
4401064560
>>> id(y)
4401064560
>>> x is y
True

is显示两者是同一个对象,则返回True

请记住,在Python中,名称只是引用值的标签;您可以有多个名称指向同一个对象。is告诉您两个名称是否指向一个相同的对象。==告诉您两个名称是否引用具有相同值的对象。

You misunderstood what the is operator tests. It tests if two variables point the same object, not if two variables have the same value.

From the documentation for the is operator:

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.

Use the == operator instead:

print(x == y)

This prints True. x and y are two separate lists:

x[0] = 4
print(y)  # prints [1, 2, 3]
print(x == y)   # prints False

If you use the id() function you’ll see that x and y have different identifiers:

>>> id(x)
4401064560
>>> id(y)
4401098192

but if you were to assign y to x then both point to the same object:

>>> x = y
>>> id(x)
4401064560
>>> id(y)
4401064560
>>> x is y
True

and is shows both are the same object, it returns True.

Remember that in Python, names are just labels referencing values; you can have multiple names point to the same object. is tells you if two names point to one and the same object. == tells you if two names refer to objects that have the same value.


回答 1

另一个重复是在问为什么两个相等的字符串通常不相同,在这里并没有真正回答:

>>> x = 'a' 
>>> x += 'bc'
>>> y = 'abc'
>>> x == y
True
>>> x is y
False

那么,为什么它们不是相同的字符串?特别是考虑到这一点:

>>> z = 'abc'
>>> w = 'abc'
>>> z is w
True

让我们推迟第二部分。第一个怎么可能是真的?

解释器将必须有一个“内部表”,该表将字符串值映射到字符串对象,因此,每次尝试使用内容创建新字符串时'abc',都将获得相同的对象。维基百科对实习的工作方式进行了更详细的讨论。

Python 一个字符串实习表;您可以使用该sys.intern方法手动插入字符串。

实际上,允许 Python 自动实习任何不可变的类型,但并非必须这样做。不同的实现将产生不同的值。

CPython(如果您不知道使用的是哪种实现,则使用的实现)会自动插入小整数和一些特殊的单例,例如False,但不会自动生成字符串(或大整数,小元组或其他任何东西)。您可以很容易地看到这一点:

>>> a = 0
>>> a += 1
>>> b = 1
>>> a is b
True
>>> a = False
>>> a = not a
>>> b = True
a is b
True
>>> a = 1000
>>> a += 1
>>> b = 1001
>>> a is b
False

好的,但是为什么zw相同?

那不是解释器自动进行内插,而是编译器的折叠值。

如果相同的编译时间字符串在同一模块中出现两次(究竟这个手段是很难界定的,它是不一样的事,作为一个字符串字面量,因为r'abc''abc''a' 'b' 'c'都是不同的文字,但相同的字符串,但很容易理解直观地),编译器将只创建带有两个引用的字符串的一个实例。

实际上,编译器可以走得更远:'ab' + 'c'可以'abc'由优化器转换为编译器,在这种情况下,可以将其与'abc'常量一起折叠在同一模块中。

同样,这是允许但并非必须执行的Python。但是在这种情况下,CPython总是折叠小字符串(还有小元组)。(尽管交互式解释器的按语句陈述式编译器与一次模块编译器没有进行相同的优化,所以您不会在交互中看到完全相同的结果。)


那么,作为程序员,您应该怎么做?

好吧…什么都没有。您几乎没有任何理由关心两个不可变值是否相同。如果您想知道何时可以使用a is b而不是a == b,那么您会提出错误的问题。仅a == b在两种情况下始终使用:

  • 与单例值的比较可读性比较x is None
  • 对于可变值,当您需要知道突变是否x会影响时y

Another duplicate was asking why two equal strings are generally not identical, which isn’t really answered here:

>>> x = 'a' 
>>> x += 'bc'
>>> y = 'abc'
>>> x == y
True
>>> x is y
False

So, why aren’t they the same string? Especially given this:

>>> z = 'abc'
>>> w = 'abc'
>>> z is w
True

Let’s put off the second part for a bit. How could the first one be true?

The interpreter would have to have an “interning table”, a table mapping string values to string objects, so every time you try to create a new string with the contents 'abc', you get back the same object. Wikipedia has a more detailed discussion on how interning works.

And Python has a string interning table; you can manually intern strings with the sys.intern method.

In fact, Python is allowed to automatically intern any immutable types, but not required to do so. Different implementations will intern different values.

CPython (the implementation you’re using if you don’t know which implementation you’re using) auto-interns small integers and some special singletons like False, but not strings (or large integers, or small tuples, or anything else). You can see this pretty easily:

>>> a = 0
>>> a += 1
>>> b = 1
>>> a is b
True
>>> a = False
>>> a = not a
>>> b = True
a is b
True
>>> a = 1000
>>> a += 1
>>> b = 1001
>>> a is b
False

OK, but why were z and w identical?

That’s not the interpreter automatically interning, that’s the compiler folding values.

If the same compile-time string appears twice in the same module (what exactly this means is hard to define—it’s not the same thing as a string literal, because r'abc', 'abc', and 'a' 'b' 'c' are all different literals but the same string—but easy to understand intuitively), the compiler will only create one instance of the string, with two references.

In fact, the compiler can go even further: 'ab' + 'c' can be converted to 'abc' by the optimizer, in which case it can be folded together with an 'abc' constant in the same module.

Again, this is something Python is allowed but not required to do. But in this case, CPython always folds small strings (and also, e.g., small tuples). (Although the interactive interpreter’s statement-by-statement compiler doesn’t run the same optimization as the module-at-a-time compiler, so you won’t see exactly the same results interactively.)


So, what should you do about this as a programmer?

Well… nothing. You almost never have any reason to care if two immutable values are identical. If you want to know when you can use a is b instead of a == b, you’re asking the wrong question. Just always use a == b except in two cases:

  • For more readable comparisons to the singleton values like x is None.
  • For mutable values, when you need to know whether mutating x will affect the y.

回答 2

is仅当它们实际上是同一对象时才返回true。如果它们相同,则对另一个的更改也会出现。这是区别的一个例子。

>>> x = [1, 2, 3]
>>> y = [1, 2, 3]
>>> print x is y
False
>>> z = y
>>> print y is z
True
>>> print x is z
False
>>> y[0] = 5
>>> print z
[5, 2, 3]

is only returns true if they’re actually the same object. If they were the same, a change to one would also show up in the other. Here’s an example of the difference.

>>> x = [1, 2, 3]
>>> y = [1, 2, 3]
>>> print x is y
False
>>> z = y
>>> print y is z
True
>>> print x is z
False
>>> y[0] = 5
>>> print z
[5, 2, 3]

回答 3

重复的问题提示,此类推可能会起作用:

# - Darling, I want some pudding!
# - There is some in the fridge.

pudding_to_eat = fridge_pudding
pudding_to_eat is fridge_pudding
# => True

# - Honey, what's with all the dirty dishes?
# - I wanted to eat pudding so I made some. Sorry about the mess, Darling.
# - But there was already some in the fridge.

pudding_to_eat = make_pudding(ingredients)
pudding_to_eat is fridge_pudding
# => False

Prompted by a duplicate question, this analogy might work:

# - Darling, I want some pudding!
# - There is some in the fridge.

pudding_to_eat = fridge_pudding
pudding_to_eat is fridge_pudding
# => True

# - Honey, what's with all the dirty dishes?
# - I wanted to eat pudding so I made some. Sorry about the mess, Darling.
# - But there was already some in the fridge.

pudding_to_eat = make_pudding(ingredients)
pudding_to_eat is fridge_pudding
# => False

回答 4

isis not是Python中的两个身份运算符。is运算符不比较变量的值,而是比较变量的标识。考虑一下:

>>> a = [1,2,3]
>>> b = [1,2,3]
>>> hex(id(a))
'0x1079b1440'
>>> hex(id(b))
'0x107960878'
>>> a is b
False
>>> a == b
True
>>>

上面的例子显示,你的身份(也可以在CPython的内存地址)是两个不同的ab(即使它们的值是相同的)。这就是为什么当您说a is b由于两个操作数的标识不匹配而返回false时的原因。但是,当您说时a == b,它返回true,因为==操作仅验证两个操作数的赋值是否相同。

有趣的示例(针对高级成绩):

>>> del a
>>> del b
>>> a = 132
>>> b = 132
>>> hex(id(a))
'0x7faa2b609738'
>>> hex(id(b))
'0x7faa2b609738'
>>> a is b
True
>>> a == b
True
>>>

在上面的示例中,即使ab是两个不同的变量,也a is b返回True。这是因为类型a就是int这是一个不可变的对象。因此,python(我想是为了节省内存)b在创建具有相同值的对象时分配了相同的对象。因此,在这种情况下,变量的标识匹配并a is b变为True

这将适用于所有不可变对象:

>>> del a
>>> del b
>>> a = "asd"
>>> b = "asd"
>>> hex(id(a))
'0x1079b05a8'
>>> hex(id(b))
'0x1079b05a8'
>>> a is b
True
>>> a == b
True
>>>

希望有帮助。

is and is not are the two identity operators in Python. is operator does not compare the values of the variables, but compares the identities of the variables. Consider this:

>>> a = [1,2,3]
>>> b = [1,2,3]
>>> hex(id(a))
'0x1079b1440'
>>> hex(id(b))
'0x107960878'
>>> a is b
False
>>> a == b
True
>>>

The above example shows you that the identity (can also be the memory address in Cpython) is different for both a and b (even though their values are the same). That is why when you say a is b it returns false due to the mismatch in the identities of both the operands. However when you say a == b, it returns true because the == operation only verifies if both the operands have the same value assigned to them.

Interesting example (for the extra grade):

>>> del a
>>> del b
>>> a = 132
>>> b = 132
>>> hex(id(a))
'0x7faa2b609738'
>>> hex(id(b))
'0x7faa2b609738'
>>> a is b
True
>>> a == b
True
>>>

In the above example, even though a and b are two different variables, a is b returned True. This is because the type of a is int which is an immutable object. So python (I guess to save memory) allocated the same object to b when it was created with the same value. So in this case, the identities of the variables matched and a is b turned out to be True.

This will apply for all immutable objects:

>>> del a
>>> del b
>>> a = "asd"
>>> b = "asd"
>>> hex(id(a))
'0x1079b05a8'
>>> hex(id(b))
'0x1079b05a8'
>>> a is b
True
>>> a == b
True
>>>

Hope that helps.


回答 5

x is yid(x) == id(y),比较对象的身份相同。

正如@ tomasz-kurgan在下面的注释中指出的那样,is运算符在某些对象上的行为异常。

例如

>>> class A(object):
...   def foo(self):
...     pass
... 
>>> a = A()
>>> a.foo is a.foo
False
>>> id(a.foo) == id(a.foo)
True

参考;
https://docs.python.org/2/reference/expressions.html#is-not
https://docs.python.org/2/reference/expressions.html#id24

x is y is same as id(x) == id(y), comparing identity of objects.

As @tomasz-kurgan pointed out in the comment below is operator behaves unusually with certain objects.

E.g.

>>> class A(object):
...   def foo(self):
...     pass
... 
>>> a = A()
>>> a.foo is a.foo
False
>>> id(a.foo) == id(a.foo)
True

Ref;
https://docs.python.org/2/reference/expressions.html#is-not
https://docs.python.org/2/reference/expressions.html#id24


回答 6

您可以在此处检查一个小的整数。257以上的数字不是一个小整数,因此将其计算为另一个对象。

==在这种情况下,最好使用替代方法。

更多信息在这里:http : //docs.python.org/2/c-api/int.html

As you can check here to a small integers. Numbers above 257 are not an small ints, so it is calculated as a different object.

It is better to use == instead in this case.

Further information is here: http://docs.python.org/2/c-api/int.html


回答 7

X指向一个数组,Y指向另一个数组。这些数组是相同的,但是is运算符将查看不相同的那些指针。

X points to an array, Y points to a different array. Those arrays are identical, but the is operator will look at those pointers, which are not identical.


回答 8

它比较对象标识,即变量是否引用内存中的同一对象。就像==Java或C中的(比较指针时)一样。

It compares object identity, that is, whether the variables refer to the same object in memory. It’s like the == in Java or C (when comparing pointers).


回答 9

一个简单的例子,水果

fruitlist = [" apple ", " banana ", " cherry ", " durian "]
newfruitlist = fruitlist
verynewfruitlist = fruitlist [:]
print ( fruitlist is newfruitlist )
print ( fruitlist is verynewfruitlist )
print ( newfruitlist is verynewfruitlist )

输出:

True
False
False

如果你试试

fruitlist = [" apple ", " banana ", " cherry ", " durian "]
newfruitlist = fruitlist
verynewfruitlist = fruitlist [:]
print ( fruitlist == newfruitlist )
print ( fruitlist == verynewfruitlist )
print ( newfruitlist == verynewfruitlist )

输出是不同的:

True
True
True

这是因为==运算符仅比较变量的内容。要比较2个变量的标识,请使用is运算符

要打印标识号:

print ( id( variable ) )

A simple example with fruits

fruitlist = [" apple ", " banana ", " cherry ", " durian "]
newfruitlist = fruitlist
verynewfruitlist = fruitlist [:]
print ( fruitlist is newfruitlist )
print ( fruitlist is verynewfruitlist )
print ( newfruitlist is verynewfruitlist )

Output:

True
False
False

If you try

fruitlist = [" apple ", " banana ", " cherry ", " durian "]
newfruitlist = fruitlist
verynewfruitlist = fruitlist [:]
print ( fruitlist == newfruitlist )
print ( fruitlist == verynewfruitlist )
print ( newfruitlist == verynewfruitlist )

The output is different:

True
True
True

That’s because the == operator compares just the content of the variable. To compare the identities of 2 variable use the is operator

To print the identification number:

print ( id( variable ) )

回答 10

is运营商不过是英文版的==。由于两个列表的ID不同,因此答案为假。你可以试试:

a=[1,2,3]
b=a
print(b is a )#True

*因为两个列表的ID都相同

The is operator is nothing but an English version of ==. Because the IDs of the two lists are different so the answer is false. You can try:

a=[1,2,3]
b=a
print(b is a )#True

*Because the IDs of both the list would be same