为什么在相同的python代码上List比Dict更快?

时间:2018-12-25 09:23:27

标签: python python-3.x

我已经写了一个有关动态编程的函数。

递归公式为

  

T(n)= T(0)* T(n-1)+ T(1)* T(n-2)+…+ T(n-1)* T(0)

如您所见,T(n)的值取决于T(0) … T(n-1)的值。

在这个问题上,我需要存储T(0) … T(n-1)来计算T(n)

但是哪种数据结构最好?

  

假设我们已经完成了T(0) … T(5)的计算。我们需要计算T(6)

     

我们可以将T存储为以下结构:

     
    

T = [1,1,2,5,14,42,0]

         

T = {0:1,1:1,2:2,3:5,4:14,5:42,6:0}

  

我的答案最初是dict,因为获取T(k)的时间复杂度是O(1)

然而,listdict都经过测试。测试结果表明listdict更快。 为什么?

我使用n = 1000测试程序。

import timeit
def test(n, T):
    T[0] = 1
    # calculate T[i]
    # we need to calculate T[0]-> T[n-1] at first.
    for i in range(1,n+1): 
        for j in range(i):
            T[i] += T[j]*T[i-1-j]
    return T[n]

# initial list T
T_1 = [0]*1001 

# initial dict T
T_2 = {} 
for i in range(1001):
    T_2[i] = 0

t = timeit.timeit(stmt="test(1000,T_1)",setup="from __main__ import test,T_1;",number=10)
print("store T with list, total time is:",t)
t = timeit.timeit(stmt="test(1000,T_2)",setup="from __main__ import test,T_2;",number=10)
print("store T with dict, total time is:",t)

运行结果为:

  

包含列表的T商店,总时间为:6.454328614287078

     

带有dict的T商店,总时间为:6.761199993081391

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

TLDR:词典使用哈希查找值,这会增加一些开销。还有可能会发生碰撞,从而导致解决问题的成本更高。

长答案:

哈希:
字典被实现为哈希表,哈希表是一种在内部将值存储在数组中的数据结构。它通过将键传递给哈希函数来确定要使用的索引。哈希函数将产生一个在内部数组范围内的值。这是一种通过键而不是索引来查找项目的相对快速的方法。但是,由于每次都需要运行此哈希函数,因此它仍然比直接按索引查找要慢。

碰撞:
在大多数情况下,词典无法完美避免冲突。内部数组可以实现为链接列表的数组,也可以使用其他技术解决冲突。如果数据集变化缓慢或永不变化,则可以避免冲突。为给定的数据集创建完美的哈希函数。没有所有数据集的通用完美哈希函数,这是不可能的。因此,通用字典(例如Python中提供的字典)必须实现冲突解决。

哪种数据结构更好?这取决于数据的映射方式。

如果您可以将其映射到具有很少间隙的连续整数键(例如0、1、2、3、4、5等),则数组(python中的列表)可能是最佳选择

如果您的数据集具有非整数键,则词典是最佳选择。这就是它的设计目的。

如果您的整数键的间隔较大,则与列表相比,字典将节省大量内存,因为列表必须包含大量浪费的索引。