在dict中的运行时间与==相比

时间:2016-05-16 10:14:15

标签: python performance python-3.x

在考试中,我被问到以下哪项功能最有可能跑得更快:

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跑得更快。

任何解释都将不胜感激。

2 个答案:

答案 0 :(得分: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)。

答案 1 :(得分:0)

  

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

- 不,不是。

对于词典和集合的in的复杂性是平均O(1)和最差(具有大量冲突)直到O(N)。 为了更好地理解哈希表,词组,集合等如何工作,请阅读此内容 - How are Python's Built In Dictionaries Implemented