字符串元组"是"比较行为不一致

时间:2016-07-15 22:09:46

标签: python python-3.x

我很困惑。

foo = ("empty", 0)
foo[0] is "empty"

返回False。这似乎是关键字字符串的一个问题,因为" list"也失败了。 "抢先"和其他字符串返回true。这似乎只发生在元组中,好像foo是一个列表,代码也返回true

我已经用python 3.4.3和python 3.5对它进行了测试,两者都表现得这样,但python2.7似乎没有这个问题,并按预期返回true。

我在python3中错过了元组的一些标准吗?我试图谷歌解决这个问题,但我的目标很短。

修改: 为了清理问题,我的确切问题是为什么

foo = ("empty", 0)
foo[0] is "empty"

返回False,但

foo = ("empt", 0)
foo[0] is "empt"

返回True?

3 个答案:

答案 0 :(得分:0)

a is b

等于

id(a) == id(b)

如前所述Comparing strings 还读这个 Built-in Functions - id

答案 1 :(得分:0)

正如已经提到的其他答案:您正在按身份比较字符串,这可能会失败。关于字符串文字的身份的假设是不可能的。

然而,你实际上发现了一个微妙的问题。

>>> t = ("list",); t[0] is "list"
False
>>> t = ("notlist",); t[0] is "notlist"
True
>>> t = ("list",)
>>> id(t[0])
140386135830064
>>> id("list")
140386137208400
>>> t[0] is "list"
False
>>> l = ("notlist",)
>>> id(l[0])
140386135830456
>>> id("notlist")
140386135830456
>>> l[0] is "notlist"
True
# interestingly, this works:
>>> ("list",)[0] is "list"
True

(使用Python 3.5.1+交互式shell测试)

这显然是python的一些组件依赖于实现的行为,可能是词法分析器或解析器。

底线:只要您不依赖于对象标识,就可以使用==进行字符串比较。

答案 2 :(得分:0)

使用is的文字值几乎肯定会给你一个依赖于实现的结果。 Python保证成为单例的唯一文字是None。任何其他文字可能会或可能不会解析为对现有对象的引用。您不能假设解释器将“识别”重复值并使用相同的底层对象来表示它。