理解Python';s";是";操作人员
理解Python';s";是";操作人员,python,operators,Python,Operators,is运算符与变量的值不匹配,但 实例本身 这到底是什么意思 我声明了两个名为x和y的变量,在两个变量中分配相同的值,但使用is运算符时返回false 我需要澄清一下。这是我的密码 x = [1, 2, 3] y = [1, 2, 3] print(x is y) # It prints false! 您误解了是什么操作员测试。它测试两个变量是否指向同一对象,而不是两个变量是否具有相同的值 从以下文件: 运算符为且不为测试对象标识:x为y当且仅当x和y为同一对象时为真 请改用=运算符: pr
is
运算符与变量的值不匹配,但
实例本身
这到底是什么意思
我声明了两个名为x
和y
的变量,在两个变量中分配相同的值,但使用is
运算符时返回false
我需要澄清一下。这是我的密码
x = [1, 2, 3]
y = [1, 2, 3]
print(x is y) # It prints false!
您误解了
是什么
操作员测试。它测试两个变量是否指向同一对象,而不是两个变量是否具有相同的值
从以下文件:
运算符为
且不为
测试对象标识:x为y
当且仅当x
和y
为同一对象时为真
请改用=
运算符:
print(x == y)
这将打印True
<代码>x和y
是两个单独的列表:
如果使用,您将看到x
和y
具有不同的标识符:
>>> id(x)
4401064560
>>> id(y)
4401098192
但如果要将y
指定给x
,则两者都指向同一对象:
>>> x = y
>>> id(x)
4401064560
>>> id(y)
4401064560
>>> x is y
True
而is
显示两者都是相同的对象,它返回True
记住,在Python中;可以有多个名称指向同一对象
is
告诉您两个名称是否指向同一个对象=
告诉您两个名称是否引用具有相同值的对象。X指向一个数组,Y指向另一个数组。这些数组是相同的,但是is
操作符将查看那些不相同的指针。它比较对象标识,即变量是否引用内存中的相同对象。这类似于Java或C中的=
(在比较指针时)。您可以在这里检查一个小整数。257以上的数字不是一个小整数,因此它被计算为一个不同的对象
在这种情况下,最好使用==
更多信息如下:
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]
在a的提示下,这种类比可能有效:
# - 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
我在问为什么两个相等的字符串通常不相同,这里并没有回答:
>>> x = 'a'
>>> x += 'bc'
>>> y = 'abc'
>>> x == y
True
>>> x is y
False
那么,为什么它们不是相同的字符串呢?特别是考虑到这一点:
>>> z = 'abc'
>>> w = 'abc'
>>> z is w
True
让我们把第二部分推迟一会儿。第一个怎么可能是真的 解释器必须有一个“interning table”,一个将字符串值映射到字符串对象的表,因此每次尝试使用内容
'abc'
创建新字符串时,都会返回相同的对象。更详细地讨论了实习的工作原理
Python有一个字符串插入表;您可以使用该方法手动插入字符串
事实上,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
好的,但是为什么
z
和w
是相同的呢
这不是解释器自动插入,而是编译器折叠值
如果同一个编译时字符串在同一个模块中出现两次(很难准确地定义它的含义,因为r'abc'
,'abc'
和'a''b''c'
都是不同的文本,但都是相同的字符串,但很容易直观地理解),编译器将只创建一个字符串实例和两个引用
事实上,编译器可以更进一步:优化器可以将'ab'+'c'
转换为'abc'
,在这种情况下,它可以与同一模块中的'abc'
常量折叠在一起
同样,Python允许但不要求这样做。但在这种情况下,CPython总是折叠小字符串(以及小元组)。(尽管交互式解释器的逐语句编译器没有运行与每次模块编译器相同的优化,因此您不会以交互方式看到完全相同的结果。)
那么,作为一名程序员,你应该怎么做呢 没什么。如果两个不可变的值是相同的,您几乎没有任何理由关心。如果您想知道何时可以使用
a is b
而不是a==b
,您问的问题是错误的。只要始终使用a==b
,以下两种情况除外:
- 要与单例值进行更可读的比较,如
x为None
- 对于可变值,当您需要知道变异
是否会影响x
时y
是
和不是
是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
>>>
上面的示例显示,a
和b
的标识(也可以是Cpython中的内存地址)不同(即使它们的值相同)。这就是为什么当您说a是b
时,由于两个操作数的标识不匹配,它返回false。但是,当您说a==b
时,它返回true,因为=
操作仅验证两个操作数是否具有相同的赋值
有趣的例子(对于加分):
在上面的示例中,即使a
和b
是两个不同的变量,a返回b
<
>>> a = [1,2,3]
>>> b = [1,2,3]
>>> hex(id(a))
'0x1079b1440'
>>> hex(id(b))
'0x107960878'
>>> 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
>>>
>>> del a
>>> del b
>>> a = "asd"
>>> b = "asd"
>>> hex(id(a))
'0x1079b05a8'
>>> hex(id(b))
'0x1079b05a8'
>>> a is b
True
>>> a == b
True
>>>
>>> class A(object):
... def foo(self):
... pass
...
>>> a = A()
>>> a.foo is a.foo
False
>>> id(a.foo) == id(a.foo)
True
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
print ( id( variable ) )
a=[1,2,3]
b=a
print(b is a )#True