如何在Python中设置字典的初始大小?

问题描述:

我将约400万个不同的密钥放入Python字典中。 创建此字典需要大约15分钟,并在我的机器上消耗大约4GB的内存。字典完全创建后,查询字典很快。如何在Python中设置字典的初始大小?

我怀疑字典创建是非常耗费资源的,因为字典经常被重新编译(随着它的增长)。 是否可以创建一个Python的字典与一些初始大小或桶号?

我的字典从一个数字指向一个对象。

class MyObject(object): 
    def __init__(self): 
    # some fields... 

d = {} 
d[i] = MyObject() # 4M times on different key... 
+0

非常类似于http://*.com/questions/311775/python-create-a-list-dict-with-initial-capacity – 2009-08-19 09:13:52

+0

你能让我们知道你的密钥的来源/格式,所以我们可以改进an鱼? – 2009-08-19 09:39:44

+0

它是一个数字的关键 – tkokoszka 2009-08-19 10:09:11

由于性能问题,最好测量。这里有一些时间:

d = {} 
for i in xrange(4000000): 
    d[i] = None 
# 722ms 

d = dict(itertools.izip(xrange(4000000), itertools.repeat(None))) 
# 634ms 

dict.fromkeys(xrange(4000000)) 
# 558ms 

s = set(xrange(4000000)) 
dict.fromkeys(s) 
# Not including set construction 353ms 

最后一个选项不做任何调整大小,它只是从集合中复制散列并增加引用。正如你所看到的,调整大小并没有花费很多时间。这可能是你的对象创建缓慢。

+0

无论如何初始化字典,填充数据总是需要很长时间。看起来确实所有的时间都花在创建对象上。谢谢! – tkokoszka 2009-08-19 10:32:21

你可以尝试从内容与dict.fromkeys类方法填充分隔密钥散列。它将创建一个已知大小的dict,所有值默认为None或您选择的值。之后,您可以遍历它来填充值。它会帮助你计算所有密钥的实际散列。不知道你是否能够显着提高速度。

如果您DATAS需要/可以存储在光盘上或许您可以将您的DATAS在BSDDB database或使用Cpickle加载/存储您的dictionnary

如果你知道C,你可以看看dictobject.cthe Notes on Optimizing Dictionaries 。您会注意到参数PyDict_MINSIZE:

PyDict_MINSIZE。目前设置为8.

此参数在dictobject.h中定义。所以你可能编译Python时改变它,但这可能是一个坏主意。

我尝试:

a = dict.fromkeys((range(4000000))) 

它创建在约3秒,4个000 000项的字典。之后,设定值非常快。所以我认为dict.fromkey是最快的方式。

+4

+1提到dict.fromkeys()。但是,使用range()来指定键意味着你最终得到了顺序键的字典。如果这是必需的,为什么不使用列表?a = [None] * 4000000 – 2009-08-19 09:53:23

+1

这不是直接的解决方案,只是一个演示,你可以使用键来预先生成字典在一个非常排序的时间。 – 2009-08-19 11:47:28

+1

符合@ShawnChin提出的观点,如果你不希望数字1 ... 4M作为关键字?或者更一般地说,如果你事先不知道你的钥匙,但你只知道他们有几百万? – posdef 2016-03-10 11:29:32

你是否用初始化所有键的新“空”相同类型的实例?是不是可以写一个defaultdict或什么东西来创建访问它时的对象?