Alt*_*Alt 10 python dictionary hashtable python-2.7
我正在使用python字典来保存大量对象,并且每个对象都有一个字符串名称.具体来说,这是我的代码:
from itertools import product
for (i,j,k) in product(range(N),range(M),range(K)):
var_name='x_'+'_'+str(i)+str(j)+'_'+str(k)
var_dict[var_name] = f(var_name,other_params)
print len(var_dict)
Run Code Online (Sandbox Code Playgroud)
f(...)返回一个对象.在我的代码中,N = 363,M = 500,K = 2.所以我希望词典中有363000个条目.但是当我检查var_dict的长度时,它是330860!
(Pdb)len(var_dict)330860
以下是我的问题:1)有没有解释?例如,python的内置哈希表可以解决的项目数量有限制吗?
2)我该怎么做才能解决这个问题?
谢谢!
And*_*ico 13
问题出在这里:
str(i)+str(j)
Run Code Online (Sandbox Code Playgroud)
这不会产生唯一标识符.例如,当i=1和j=11将被设置的值覆盖时设置的值i=11和j=1(还有更多实例).
您可以通过在两个数字之间插入一些分隔符来解决问题(例如您之间j和之间的下划线k).
您在构造的字符串之间i和之间没有分隔符j,因此元组喜欢(12, 1, 0)并(1, 21, 0)生成相同的名称.如果可能的话,不要为这些东西命名; 直接使用数字:
var_dict[i, j, k] = f(i, j, k, other_params)
Run Code Online (Sandbox Code Playgroud)
如果f确实需要获取字符串,请更改名称构造以在i和之间放置分隔符j:
var_name = 'x_{}_{}_{}'.format(i, j, k)
Run Code Online (Sandbox Code Playgroud)
如果可能的话,即使f需要字符串,也要使用元组作为dict键:
var_dict[i, j, k] = f(var_name, other_params)
Run Code Online (Sandbox Code Playgroud)
python 字典中字符串键的访问时间约为 1 微秒 (1s / 1000 / 1000)。
花费的时间略有增加,具体取决于字典中的条目数,可能与 log(N) 缩放类似。
对于大于 2^26 = 67,108,864 的字典,性能显着下降。从大小为 2^27 = 134,217,728 的字典中读取需要 30 倍的时间,而对于大小为 2^28 = 268,435,456 的字典则需要 9000 倍的时间。我的电脑在达到 2^29 之前就耗尽了内存。
因此,对您在 python 中字典的最大大小问题的实际答案是:
2^26 = 67,108,864
>>> for i in range(1,sys.maxsize):
... key = str(i)
... d[key] = key
... if math.log2(i) % 1 == 0:
... time_start = time.perf_counter()
... value = d[key]
... time_taken = time.perf_counter() - time_start
... print(time_taken*1000*1000, i)
...
0.682000063534360 1
0.521999936609063 2
0.394000153391971 4
0.365999994755839 8
0.424000063503626 16
0.380000074073905 32
0.365000005331239 64
0.447000047643086 128
0.413999941883957 256
0.481999904877739 512
0.641000042378436 1024
0.906999957805965 2048
0.616000079389778 4096
0.995999926090007 8192
1.115000031859381 16384
1.142999963121838 32768
1.144999941971036 65536
1.156000053015304 131072
1.231999931405880 262144
1.225999994858284 524288
1.196000084746629 1048576
1.308000037170131 2097152
1.232000158779556 4194304
1.314999963142327 8388608
1.178000047730165 16777216
1.179000037154764 33554432
1.669000084802974 67108864
33.22600014143973 134217728
9655.005000013261 268435456
Killed: 9
Run Code Online (Sandbox Code Playgroud)