我有这样的dict(),
xyz = {"a":{"b":[1,2,3]}}
我想查看嵌套的dict是否有“b”或“c”键。 我可以检查一个键,如
>>> "b" in xyz.get("a",{})
True
我尝试了以下内容,
>>> "b" or "c" in xyz.get("a",{})
'b'
但是想知道我是否可以为“b”和“c”写这个陈述。 希望这是有道理的。
答案 0 :(得分:5)
any
和生成器表达式是你的朋友:
>>> xyz = {"a":{"b":[1,2,3]}}
>>> any(i in xyz.get("a",{}) for i in ["b", "c"])
True
答案 1 :(得分:2)
or
并非如此。 (这可能是StackOverflow上最常见的Python问题,但不幸的是,除非你已经知道问题是什么,否则它很难搜索...)or
只需要两个布尔表达式并返回一些东西如果他们中的任何一个都是真实的,那么你要求的是"b"
是真实的(它是),还是"c" in xyz.get("a", {})
是真的(它可能是也可能不是,但是Python没有&# 39;甚至必须检查),所以它会让你回到"b"
,这是真的。
您可以使用括号("b" or "c") in xyz.get("a", {})
来解决这个问题,但这也很糟糕。首先,它评估("b" or "c")
并获取"b"
,然后检查dict中是否存在,忽略"c"
。
等同句在英语中有意义的原因在于你隐含地要求"在dict中是b,在dict中是c;&#34 ;; Python不会让你隐瞒,但你可以随时明确说明:
"b" in xyz.get("a", {}) or "c" in xyz.get("a", {})`
如果您想要执行其中两项(或者只是动态识别它们),那么您将要使用any
和/或存储xyz.get("a", {})
在一个临时变量而不是重复它,就像在utdemir的答案中 - 或者甚至更好,使用一套,如Kasra的答案。
答案 2 :(得分:1)
您可以使用set.intersection
:
>>> bool({'b','c'}.intersection(xyz.get('a')))
True
以下基准测试显示其效率高于any
:
:~$ python -m timeit "xyz = {'a':{'b':[1,2,3]}};any(i in xyz.get('a',{}) for i in ['b', 'c'])"
1000000 loops, best of 3: 0.932 usec per loop
:~$ python -m timeit "xyz = {'a':{'b':[1,2,3]}};bool({'b','c'}.intersection(xyz.get('a')))"
1000000 loops, best of 3: 0.649 usec per loop
但是@ abarnert在这种情况下的答案最快:
~$ python -m timeit "xyz = {'a':{'b':[1,2,3]}};'b' in xyz.get('a', {}) or 'c' in xyz.get('a', {})"
1000000 loops, best of 3: 0.325 usec per loop