Python 中的字符串比较:is vs. == [duplicate]

String comparison in Python: is vs. == [duplicate]

提问人:Coquelicot 提问时间:6/7/2010 最后编辑:Coquelicot 更新时间:12/7/2016 访问量:1100225

问:

我注意到我正在编写的一个 Python 脚本表现得很松鼠,并将其跟踪到一个无限循环,其中循环条件是 。在调试器中运行它,结果发现该行实际上是 .当我将其更改为 而不是 时,它工作正常。while line is not ''''!=''is not ''

此外,通常认为默认情况下只使用“==”是否更好,即使在比较 int 或 Boolean 值时也是如此?我一直喜欢使用“is”,因为我发现它更美观和更像python(这就是我落入这个陷阱的原因......),但我想知道它是否只是为了在你关心寻找两个具有相同id的对象时保留。

Python 字符串 比较 相等

评论

3赞 codetaku 7/16/2014
这如何“与你的经验背道而驰”?NaN 是唯一内置的反例;你只是误解了方向关系。规范说“对于所有内置的 Python 对象(如字符串、列表、字典、函数等),如果 x 是 y,那么 x==y 也是 True.”,而不是“对于所有内置的 Python 对象(如字符串、列表、字典、函数等),如果 x==y,那么 x 是 y 也是 True。出于某种原因,你假装它说的是后者。事实并非如此。你看到相等是匹配的,但事实并非如此。前面引用的声明完全允许这样做。
0赞 Coquelicot 8/22/2014
是的。我对此的解读完全混乱。我把它编辑出来了,因为我认为它对未来的读者没有用。
2赞 Jadav Bheda 10/26/2016
O1 是 O2 =>比较 O1 和 O2 是否都指向内存中的同一物理位置(换句话说,如果它们是同一个对象)。而 o1 == o2 =>这里 python 调用 o1 的 __cmp__(o2) 方法,理想情况下应该比较值并返回 True 或 False。(换句话说,它比较价值)对于 JAVA 用户:在 Java 中,通过使用 str1 == str2 来确定两个字符串变量是否引用相同的物理内存位置。(称为对象标识,它是用 Python 编写的,因为 str1 是 str2)。要比较 Java 中的字符串值,请使用 str1.equals(str2);在 Python 中,使用 str1 == str2。

答:

27赞 pycruft 6/7/2010 #1

这个问题

你的阅读逻辑

对于所有内置的 Python 对象(如 字符串、列表、字典、函数、 等),如果 x 是 y,那么 x==y 也是 真。

略有瑕疵。

如果适用,则为 True,但不会反向应用。 可能产生 True,而产生 False。is====is

评论

0赞 Mike Boers 6/7/2010
isimpile 仅对内置类型必须为 true。人们可以很容易地编写一个对象不等于自身的类。==
0赞 12/18/2015
通过说“如果适用,那么它将是 True,但它不会反过来应用”,你只是在陈述 OP 观察到的内容。is==
667赞 dan04 6/7/2010 #2

对于所有内置的 Python 对象(如 字符串、列表、字典、函数、 等),如果 x 是 y,那么 x==y 也是 真。

并非总是如此。NaN 就是一个反例。但通常,恒等式()意味着相等()。反之则不然:两个不同的对象可以具有相同的值。is==

另外,通常认为默认情况下只使用“==”更好,甚至 在比较 int 或 Boolean 值时?

在比较值和比较标识时使用。==is

在比较整数(或一般的不可变类型)时,你几乎总是想要前者。有一个优化允许将小整数与 进行比较,但不要依赖它。is

对于布尔值,您根本不应该进行比较。而不是:

if x == True:
    # do something

写:

if x:
    # do something

对于比较 ,优于 。Noneis None== None

我一直喜欢使用“is”,因为 我发现它在美学上更令人愉悦 和pythonic(这就是我陷入的方式 这个陷阱...),但我想知道是不是 打算只保留到什么时候 你关心的是找到两个对象 具有相同的 ID。

是的,这正是它的用途。

评论

4赞 dan04 6/7/2010
@Coquelicot:这是行不通的,因为 Python 允许将任何东西用作布尔表达式。如果您有 bool_a == 3 和 bool_b == 4,则bool_a != bool_b,但bool_a xor bool_b 为 false(因为这两个项都为 true)。
4赞 dan04 6/7/2010
@Mike:始终为 True。但这并不意味着.NaN 被定义为不等于自身。x is xx == x
3赞 estani 10/30/2012
关于速度,我虽然检查字符串是否被修改(例如从 re.sub 返回的结果)比较大字符串是否相等而不是会更快。情况并非如此,一次它显示速度仅提高了 0.4%。就我而言,re.sub 将来开始更改字符串的风险是不值得的。is==
5赞 RyPeck 11/16/2013
对于多年后的任何人来说,这仍然适用于 Python 3。
2赞 dan04 2/16/2016
@beauxq:尝试nan = float('nan'); nan is nan; nan == nan
281赞 pygabriel 6/7/2010 #3

我想举一个小例子来说明如何和参与不可变类型。试试:is==

a = 19998989890
b = 19998989889 +1
>>> a is b
False
>>> a == b
True

is比较内存中的两个对象,比较它们的值。例如,您可以看到 Python 缓存了小整数:==

c = 1
b = 1
>>> b is c
True

在比较值和比较标识时,应使用。(此外,从英语的角度来看,“equals”与“is”不同。==is

评论

6赞 B Robster 6/18/2013
另一个简单的例子,==> True 但 ==> False,因为它们是等效的日期对象,但它们仍然是不同的对象。datetime.date.today() == datetime.date.today()datetime.date.today is datetime.date.today()
5赞 hobs 3/25/2014
您的建议避免的另一个危险示例:评估结果为,但评估结果为str(None) is 'None'Falsestr(None) == 'None'True
8赞 ariddell 2/3/2015
下面是一个带有字符串的字符串:x = 'foo'; y = 'bar'.replace('bar', 'foo'); (x is y) == False
4赞 Emre Sevinç 8/14/2015
我喜欢的另一个例子:'a'*50 == 'a'*50(返回 True),而 'a'*50 是 'a'*50(返回 False)
76赞 xubio 5/10/2013 #4

逻辑没有缺陷。声明

如果 x 是 y,那么 x==y 也是 True

永远不应该被理解为意味着

如果 x==y 则 x 为 y

对于读者来说,假设逻辑陈述的反面是正确的是一个逻辑错误。参见 http://en.wikipedia.org/wiki/Converse_(逻辑)

评论

1赞 12/18/2015
@BrentHronik 它更多地与对象的内存地址和对象相关,而不是实际逻辑。id
0赞 Heather 9/4/2017
如果 x 和 y 都是 NaN,第一个语句是否成立?甚至可能使用相同的对象 ID?在其他语言(C++)中,NaN永远不会等于自身。