我注意到我正在编写的一个python脚本表现得很松懈,并将其跟踪到一个无限循环,其中循环条件是while line is not ''。在调试器中运行它,结果发现行实际上是''。当我把它改成!=''而不是is not ''时,它工作得很好。
此外,在默认情况下,即使在比较int或boolean值时,也只使用"=="更好吗?我一直喜欢用"i s"这个词,因为我觉得它在美学上更讨人喜欢,而且更像Python(我就是这样掉进这个陷阱的…),但我想知道,它是否只是为了在你想找到两个ID相同的物体时使用。
- 这与你的经历"背道而驰"吗?南是唯一的内建反例,你只是误解了方向关系。规范说"对于所有内置的python对象(如字符串、列表、dict、函数等),如果x是y,那么x==y也是真的。"而不是"对于所有内置的python对象(如字符串、列表、dict、函数等),如果x==y,那么x也是真的。"出于某种原因,您假装它说的是后者。它没有。你看到平等匹配,但不匹配。这是前一句引述的语句所完全允许的。
- 是的。我对那件事的理解完全不清楚。我把它从问题中删掉了,因为我认为它对未来的读者没有用处。
- o1是o2=>比较o1和o2是否都指向内存中相同的物理位置(换句话说,如果它们是相同的对象)。而o1==o2=>这里python调用o1的uuu cmp_uuuuuu2方法,理想情况下应该比较该值并返回true或false。(换句话说,它比较值)为Java人:在Java中,通过使用STR1==STR2来确定两个字符串变量是否引用相同的物理内存位置。(称为对象标识,用python编写时,str1是str2)。比较Java中的字符串值,UsReST1.0(Str2);在Python中,使用STR1==STR2。
For all built-in Python objects (like
strings, lists, dicts, functions,
etc.), if x is y, then x==y is also
True.
并不总是这样。Nan就是一个反例。但通常,同一性(is表示平等(==)。相反,两个不同的对象可以有相同的值。
Also, is it generally considered better to just use '==' by default, even
when comparing int or Boolean values?
比较值时使用==,比较身份时使用is。
当比较整数(或通常的不可变类型)时,您几乎总是想要前者。有一个优化允许将小整数与is进行比较,但不依赖于它。
对于布尔值,根本不应该进行比较。而不是:
1 2
| if x == True:
# do something |
写:
与None相比,is None优于== None。
I've always liked to use 'is' because
I find it more aesthetically pleasing
and pythonic (which is how I fell into
this trap...), but I wonder if it's
intended to just be reserved for when
you care about finding two objects
with the same id.
是的,这正是它的目的。
- 谢谢,回答得很清楚。我不确定我是否同意比较布尔值(除非你只是想说你不应该比较布尔值)。如果我有两个布尔变量或表达式,我会认为做bool_a是有效的!=bool_b是xor的简写。
- @coquelicot:这不起作用,因为Python允许将任何内容用作布尔表达式。如果你有bool_a==3和bool_b==4,那么bool_a!=bool_b,但是bool_a xor bool_b是假的(因为这两个术语都是真的)。
- 南:以东十一〔四〕给我以东十一〔五〕给我。这是一个怎样的反例?
- @迈克:江户十一〔六〕总是对的。但这并不意味着x == x。NaN被定义为不等于自身。
- @dan04如果bool_a的值是3,那么它不是布尔类型…
- @coquelicot:在python中,每个对象都有一个到bool的隐式转换。
- @DAN04不会改变类型(3)不是"bool"的事实。
- @coquelicot:在任何情况下,bool(a) != bool(b)等同于a ⊕ b。
- 关于速度,我认为检查字符串是否被修改(例如,从re.sub返回的结果)比较大字符串是否与is相等而不是==相等会更快。这几乎不是一次,它只显示了0.4%的速度提高。在我的例子中,re.sub在未来开始改变字符串的风险是不值得的。
- 对于以后查看这些年的任何人来说,这仍然适用于Python3。
- @Estani,您的建议有助于避免Python中最阴险的Gotchas之一,将None转换为字符串的比较:str(None) is 'None'的计算结果为False,而str(None) == 'None'的计算结果为true。在评估数据库查询结果时,这通常是必需的。尽管转换为str(不可变类型)并且控制台中的两个str对象看起来相同(和repr相同),但仍保留none的对象标识。我无法想象有任何应用程序需要使用is而不是==来比较字符串。
- 我应该用什么来比较字符串?
- @__,使用==比较字符串是否相等。几乎总是使用==。
- 我找不到任何代码显示Nan是一个反例。float("nan")是float("nan")false
- @Beauxq:试试nan = float('nan'); nan is nan; nan == nan。
- 谁决定对一个5.7岁的回答给我一个无法解释的否决票?
- 这让我想到:"foo" == u"foo","foo" is not u"foo"
我想举一个例子,说明is和==是如何涉及不可变类型的。试试看:
1 2 3 4 5 6
| a = 19998989890
b = 19998989889 +1
>>> a is b
False
>>> a == b
True |
is比较内存中的两个对象,==比较它们的值。例如,您可以看到小整数被python缓存:
1 2 3 4
| c = 1
b = 1
>>> b is c
True |
比较值时应使用==,比较身份时应使用is。(同样,从英语的角度来看,"等于"不同于"是"。)
- 另一个简单的例子,datetime.date.today() == datetime.date.today()=>对,但datetime.date.today is datetime.date.today()=>错,因为它们是等价的日期对象,但它们仍然是不同的对象。
- 您建议避免的另一个危险例子是:str(None) is 'None'的评估结果为False,而str(None) == 'None'的评估结果为True。
- 这里有一个带弦的:x = 'foo'; y = 'bar'.replace('bar', 'foo'); (x is y) == False。
- 我喜欢的另一个例子是:"a"*50=="a"*50(返回真),而"a"*50是"a"*50(返回假)。
逻辑没有缺陷。声明
if x is y then x==y is also True
不应该被解读为
if x==y then x is y
读者认为逻辑语句的逆命题是正确的,这是一个逻辑错误。参见http://en.wikipedia.org/wiki/converse_uu(逻辑)
- 不知道为什么没有更多的赞成票。
- @它与对象的内存地址和id更相关,而不是实际的逻辑。
- 如果x和y都是NaN,第一个语句是真的吗?可能有相同的对象ID?在其他语言(C++)中,假设楠永远不等于自身。
看到这个问题
你的阅读逻辑
For all built-in Python objects (like
strings, lists, dicts, functions,
etc.), if x is y, then x==y is also
True.
有点瑕疵。
如果is适用,那么==是正确的,但它不适用于相反的情况。==可能产生真,而is可能产生假。
- 哎呀,显然我忘了暗示是怎么起作用的。谢谢。还有,有人在我写作的时候问了这样一个类似的问题,这是多么奇怪啊。
- is意味着==只对内置类型有效。可以很容易地编写一个对象不等于自身的类。
- @Coquelicot在奇怪的世界范围内大约有5到5.5个动物着陆者。
- @coquelicot-一点也不奇怪。这是python中常见的混淆点,python是一种流行的语言,stack overflow是一个常见的提问网站。
- 如果说"如果is适用,那么==将是正确的,但它不适用于相反的情况。"你只是说明了OP观察到的情况。