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

tko*_*zka 19 python performance dictionary

我将大约400万个不同的密钥放入Python字典中.创建此字典大约需要15分钟,并且在我的计算机上占用大约4GB的内存.完全创建字典后,查询字典很快.

我怀疑字典创建是如此耗费资源,因为字典经常被重新定义(因为它大大增长).是否可以在Python中创建一个具有一些初始大小或桶号的字典?

我的字典从数字指向对象.

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

d = {}
d[i] = MyObject()  # 4M times on different key...
Run Code Online (Sandbox Code Playgroud)

Ant*_*sma 31

对于性能问题,最好进行衡量.以下是一些时间安排:

 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
Run Code Online (Sandbox Code Playgroud)

最后一个选项不进行任何大小调整,它只是从集合中复制哈希值并递增引用.正如您所看到的,调整大小并不需要花费很多时间.可能你的对象创建很慢.


e-s*_*tis 9

我试过了 :

a = dict.fromkeys((range(4000000)))
Run Code Online (Sandbox Code Playgroud)

它在大约3秒内创建了一个包含4 000 000个条目的字典.之后,设置值非常快.所以我猜dict.fromkey肯定是要走的路.

  • 提及dict.fromkeys()的+1.但是,使用range()来指定键意味着你最终得到了连续键的dict.如果这是必需的,为什么不使用列表呢?a = [无]*4000000 (5认同)
  • 与@ShawnChin 提出的观点一致,如果您不想要数字 1...4M 作为键怎么办?或者更笼统地说,如果您事先不知道您的密钥,但您只知道它们有数百万个怎么办? (3认同)

小智 7

如果您了解C,可以查看dictobject.c优化词典的注释.你会注意到参数PyDict_MINSIZE:

PyDict_MINSIZE.目前设为8.

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