【问题标题】:Dict has key from list字典具有列表中的键
【发布时间】:2010-12-16 19:17:56
【问题描述】:

如何确定任何列表元素是否是 dict 的键? 直接的方法是,

for i in myList:
   if i in myDict:
      return True
return False

但是有更快/更简洁的方法吗?

【问题讨论】:

  • @Dario:可能是嘘声,但我想答案还是一样的。

标签: python list dictionary


【解决方案1】:

除了any(item in my_dict for item in my_list) 来自@Ronny's answer

any(map(my_dict.__contains__, my_list)) # Python 3.x

或者:

from itertools import imap
any(imap(my_dict.__contains__, my_list)) # Python 2.x

衡量相对表现

需要考虑的案例:

  1. 列表开头的项目在字典中。
  2. 列表末尾的项目在字典中。
  3. 字典中没有列表中的项目。

比较函数(参见main.py):

def mgag_loop(myDict, myList):
    for i in myList:
        if i in myDict:
            return True
    return False

def ronny_any(myDict, myList):
    return any(x in myDict for x in myList)

def ronny_set(myDict, myList):
    return set(myDict) & set(myList)

def pablo_len(myDict, myList):
    return len([x for x in myList if x in myDict]) > 0

def jfs_map(my_dict, my_list):
    return any(map(my_dict.__contains__, my_list))

def jfs_imap(my_dict, my_list):
    return any(imap(my_dict.__contains__, my_list))

结果:mgag_loop() 在所有情况下都是最快的。

1。列表开头的项目在字典中。

def args_key_at_start(n):
    'Make args for comparison functions "key at start" case.'
    d, lst = args_no_key(n)
    lst.insert(0, n//2)
    assert (n//2) in d and lst[0] == (n//2)
    return (d, lst)

2。列表末尾的项目在字典中。

def args_key_at_end(n):
    'Make args for comparison functions "key at end" case.'
    d, lst = args_no_key(n)
    lst.append(n//2)
    assert (n//2) in d and lst[-1] == (n//2)
    return (d, lst)

3。列表中没有任何项目在字典中。

def args_no_key(n):
    'Make args for comparison functions "no key" case.'
    d = dict.fromkeys(xrange(n))
    lst = range(n, 2*n+1)
    assert not any(x in d for x in lst)
    return (d, lst)

如何重现

下载main.pymake-figures.py,运行python main.py(应安装numpymatplotlib 以创建绘图)。

要更改输入列表的最大大小,要绘制的点数相应地提供--maxn--npoints。示例:

$ python main.py --maxn 65536 --npoints 16

【讨论】:

  • any 的主要优势是短路,any(map(... 失去了这个主要优势!
  • 太棒了。我不太了解python,今天通过阅读所有答案学到了很多东西。你的总结很棒。你应该得到答案! :-)
  • 天啊。我明天晚上回去测试。
  • @Alex:你是对的。我已经澄清“地图”变体适用于 Python 3.x
  • 我在两者之间进行了测试,特别是 len([x for x in nodeList if x in removeNode]) > 0 vs def mgag_loop(myDict, myList): for i in myList: if i in myDict : return True return False 三次运行的结果几乎相同(每次运行约 80 秒),误差在 1% 以内。第二个选项总是更快,但余量很小。
【解决方案2】:
#!python
any(x in MyDict for x in MyList)
set(MyList).intersection(MyDict)

【讨论】:

【解决方案3】:

This was a popular answer 到一个相关问题:

>>> if all (k in foo for k in ("foo","bar")):
...     print "They're there!"
...
They're there!

您可以调整它以检查字典中是否出现任何内容:

>>> if any(k in myDict for k in ("foo","bar")):
...     print "Found one!"
...
Found one!

您可以检查键列表:

>>> if any(k in myDict for k in myList):
...     print "Found one!"
...
Found one!

【讨论】:

    【解决方案4】:

    非常感谢大家。我测试了所有答案的性能,最快的是

    return len([x for x in myList if x in myDict]) > 0
    

    但我没有尝试“设置”答案,因为我没有看到如何将它变成一行。

    【讨论】:

    • 过早的优化是万恶之源。 any() 解决方案更加优雅。
    • 仅供参考,您需要使用复选标记来表示您接受的答案,而不是像这样发布另一个答案。
    • 我看不出len() 怎么能更快。你用了什么输入法?我已经测量了所有答案的性能:stackoverflow.com/questions/1737778/dict-has-key-from-list/…
    【解决方案5】:

    假设您在谈论 python,另一种方法是:

    return len([x for x in myList if x in myDict]) > 0
    

    【讨论】:

    • 两个问题:这不必要地建立了一个列表并在没有短路的情况下查找所有出现。
    猜你喜欢
    • 1970-01-01
    • 2019-11-04
    • 1970-01-01
    • 1970-01-01
    • 2019-10-05
    • 2019-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多