【问题标题】:Running time of in dict compare to ==dict中的运行时间比较==
【发布时间】:2016-05-16 10:14:15
【问题描述】:

在考试中,有人问我以下哪个函数最有可能运行得更快:

def f1():
    a = []
    for j in range(100000): a.append(j*j)
    for j in range(100000):
        if 99999*j == a[j]:
            print("yes")

def f3():
    d = {}
    for j in range(100000): d[j] = j*j
    for j in range(100000):
        if 99999*j in d:
            print("yes")

很明显in== 都是 O(1)。

但是,看到f1 运行得更快,我仍然感到惊讶。

任何解释将不胜感激。

【问题讨论】:

  • 这两段代码做不同的事情。
  • 请不要破坏您的帖子。

标签: python performance python-3.x


【解决方案1】:

恒定成本是不同的。仅仅因为两个算法是 O(1) 并不意味着它们是等价的。一方面,字典只有 O(1)平均,而列表查找总是 O(1)。

您需要分析差异,但您在这里做出了错误的假设。 f1 在列表中按索引查找元素,然后测试是否相等。 f2 测试字典中的元素。但是,字典成员资格测试涉及散列和相等性测试(如果该位置有对象)。

因此,这里真正的区别在于散列与列表查找的区别。并且列表查找获胜,因为它的成本仍然是 O(1),但哈希可以是 O(N),这取决于被哈希对象的大小。差异解释了您看到的时间:

>>> import timeit
>>> a = [j * j for j in range(100000)]
>>> timeit.timeit('a[5000]', 'from __main__ import a', number=10**7)
0.26793562099919654
>>> timeit.timeit('_h(5000)', '_h = hash', number=10**7)
0.4080043680005474

散列的实际成本通常是所有字典成员查找的平均值;再加上可能的最坏情况下的 O(N) 字典查找,这使得字典查找只有 平均 O(1)。另一方面,列表查找总是 O(1)。

【讨论】:

    【解决方案2】:

    很明显,in 和 == 都是 O(1)。

    ‒ 不,不是。

    字典和集合的复杂度平均为 O(1),最差(有很多冲突)达到 O(N)。 为了更好地理解哈希表、字典、集合等是如何工作的,请阅读这个 - How are Python's Built In Dictionaries Implemented

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多