Python iterable 中的字典 items() 方法成本

Python dictionnary items() method cost inside iterable

我现在还没有进行基准测试,我想知道可迭代对象中字典的 items()(或 keys() 或 values())方法的成本。让我解释一下:

我有2本词典(当然,我真正的词典要长得多):

One = {'a': 'dontmind', 'b': 'dontmind', 'c': 'whatever'}
Two = {'a': 'dontmind', 'c': 'dontmind'}

我想检查 "Two" 的所有键是否都在 "One" 中,我会这样做:

if all([key in One.keys() for key in Two.keys()]) :
    # do stuff!

我想知道这种方式是否更好,考虑到性能:

one_keys = One.keys()
two_keys = Two.keys()
if all([key in one_keys for key in two_keys]) :
    # do stuff!

在这种情况下,keys() 方法只为每个字典调用一次。我真的不知道从字典中提取键的基本过程,以及这两种方式之间的区别是否真的很重要。你能帮帮我吗?

另外,我应该这样考虑吗?

one_keys = One.keys()
two_keys = Two.keys()
for key in two_keys :
  if key not in one_keys :
    break
else :
  # do stuff!

感谢您的回答。

为了在 2.7(但不是更早的版本)和 3.x 中获得最佳性能,我建议这样写:

if all(key in One for key in Two):
    # do stuff!

这避免了几个陷阱:

  • 生成器表达式不会像列表理解那样将整个序列拉入内存。
  • 在2.x、.keys()、returns列表中。测试列表的成员资格很慢,但测试字典的成员资格很快。在3.x、.keys()、returns一个set-like对象中,所以这不是问题。
  • 此外,该列表占用额外 space,我们将其保存在 2.7 下。 3.x 的类集合 .keys() 是现有字典的 "view",所以这在 3.x.
  • 下也不是问题

如果Python 2.x, .keys() returns 一个列表,那么多次调用它有点开销......在3.x ,它 returns 一个具有 set 行为的 dict_keys 对象,因此 3.x 最简单的是:

contains_all = two.keys() <= one.keys()

Python 2.7 中的等价物是 viewkeys:

contains_all = two.viewkeys() <= one.viewkeys()

对于早期版本,将 two 转换为一个集合并检查它是 one 的子集,例如:

contains_all = set(two).issubset(one)

Python 3.x 计时:

%timeit two.keys() <= one.keys()
# 1000000 loops, best of 3: 557 ns per loop
%timeit set(two).issubset(one)
# 1000000 loops, best of 3: 732 ns per loop
%timeit all(key in one for key in two)
# 1000000 loops, best of 3: 1.24 µs per loop

Python 2.7 计时(显示.viewkeys():

%timeit two.viewkeys() <= one.viewkeys()
# 1000000 loops, best of 3: 484 ns per loop
%timeit set(two).issubset(one)
# 1000000 loops, best of 3: 677 ns per loop
%timeit all(key in one for key in two)
# 1000000 loops, best of 3: 1.37 µs per loop