dict中var的奇怪行为

jol*_*olt 1 python

>>> x = { 'a' : 'b' , 'c' : 'd' }

>>>'a' and 'c' in x
True

>>>'a' and 'b' in x
False

>>>'b' and 'c' in x
True
Run Code Online (Sandbox Code Playgroud)

如果in <dict>钥匙检查,怎么来的最后一个看起来最多b的回报true,即使没有这样的关键b

mgi*_*son 5

你要 'b' in x and 'c' in x

您误解了and操作员的工作原理(并且您的操作符优先级错误). in具有更高的优先级and,因此您的表达式被解析为:

if 'b' and ('c' in x):
Run Code Online (Sandbox Code Playgroud)

这与:

if 'c' in x:
Run Code Online (Sandbox Code Playgroud)

因为bool('b')一直True以来'b'是一个非空字符串.

这是python中运算符优先级

请注意,即使and优先级高于in,您仍然无法得到您想要的东西,因为自从返回以来('b' and 'c') in x会减少.'c' in x'b' and 'c''c'

重写表达式的一种方法是:

if all( key in yourdict for key in ('b', 'c') ):
Run Code Online (Sandbox Code Playgroud)

仅仅需要检查2个键就太过分了,但如果您有更多要检查的键,则很快就会变得非常有用.

作为最终评论,您可能正在尝试应用运算符链接(这非常简洁).但是,有些运营商并不适合链接(in就是其中之一).表达式喜欢3 > 10 > 100 > 1000通过一些奇怪的蟒蛇黑魔法工作.根据我的经验,关系运算符很好地链接('<','>','==','<=','> ='),但大多数其他运算符不会以直观的方式链接.一般来说,

a operator b operator c operator ...
Run Code Online (Sandbox Code Playgroud)

相当于:

(a operator b) and (b operator c) and (c operator ...
Run Code Online (Sandbox Code Playgroud)


rob*_*ert 5

这相当于您目前拥有的:

>>> 'a' and ('c' in x)
True

>>> 'a' and ('b' in x)
False

>>> 'b' and ('c' in x)
True
Run Code Online (Sandbox Code Playgroud)

你想要这个:

>>> 'a' in x and 'c' in x
True

>>> 'a' in x and 'b' in x
False

>>> 'b' in x and 'c' in x
False
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用集合和<=(子集)运算符:

>>> set(['a', 'c']) <= set(x.keys())
True

>>> set(['a', 'b']) <= set(x.keys())
False

>>> set(['b', 'c']) <= set(x.keys())
False
Run Code Online (Sandbox Code Playgroud)

在Python 2.7及更高版本中,set(['a', 'c'])可以替换为{'a', 'b'}.