python2.7.6 初始化一个大字典但是内存会被用完

python2.7.6 Initialize a big dictionary but Memory would be used up

请原谅我的英语,

pythonversion:2.7.6 台式机:4cpu-核心8G内存 脚本 1:

a = {}
a['test1'] = 12345
a['test2'] = 12456
........
and so on
........
a['test4075096'] = 45637

script2:

for i in range(0,4075096):
    a['test' + str(i)] = i

结果

当我运行脚本2时,它完成得非常快 当我 运行 脚本 1 时,它需要大内存和 cpu,我的桌面卡住了

那么有谁知道这种现象背后的原因

因为在第一段代码中,python 必须逐行读取您的代码并将 CONST 值加载到内存中,而在第二部分中您已经指定了要分配的值,并且 python 将在内存中创建它们。所以 python 需要做的就是迭代 range 对象并将值分配给键。

您可以通过在您的函数上调用 dis.dis() 来查看此行为,该函数为您演示了相关字节码:

>>> def foo1():
...   a = {}
...   a['test1'] = 12345
...   a['test2'] = 12456
... 

>>> import dis
>>> 
>>> 
>>> dis.dis(foo1)
  2           0 BUILD_MAP                0
              3 STORE_FAST               0 (a)

  3           6 LOAD_CONST               1 (12345)
              9 LOAD_FAST                0 (a)
             12 LOAD_CONST               2 ('test1')
             15 STORE_SUBSCR        

  4          16 LOAD_CONST               3 (12456)
             19 LOAD_FAST                0 (a)
             22 LOAD_CONST               4 ('test2')
             25 STORE_SUBSCR        
             26 LOAD_CONST               0 (None)
             29 RETURN_VALUE        
>>> 

>>> def foo2():
...   a = {}
...   for i in range(1,10):
...        a['test + str(i)'] = i
... 
>>> dis.dis(foo2)
  2           0 BUILD_MAP                0
              3 STORE_FAST               0 (a)

  3           6 SETUP_LOOP              33 (to 42)
              9 LOAD_GLOBAL              0 (range)
             12 LOAD_CONST               1 (1)
             15 LOAD_CONST               2 (10)
             18 CALL_FUNCTION            2
             21 GET_ITER            
        >>   22 FOR_ITER                16 (to 41)
             25 STORE_FAST               1 (i)

  4          28 LOAD_FAST                1 (i)
             31 LOAD_FAST                0 (a)
             34 LOAD_CONST               3 ('test + str(i)')
             37 STORE_SUBSCR        
             38 JUMP_ABSOLUTE           22
        >>   41 POP_BLOCK           
        >>   42 LOAD_CONST               0 (None)
             45 RETURN_VALUE        
>>> 
>>> 

如果增加赋值,您会发现相关字节码也会增加:

>>> def foo1():
...    a = {}
...    a['test1'] = 12345
...    a['test2'] = 12456
...    a['test3'] = 12457
... 
>>> dis.dis(foo1)
  2           0 BUILD_MAP                0
              3 STORE_FAST               0 (a)

  3           6 LOAD_CONST               1 (12345)
              9 LOAD_FAST                0 (a)
             12 LOAD_CONST               2 ('test1')
             15 STORE_SUBSCR        

  4          16 LOAD_CONST               3 (12456)
             19 LOAD_FAST                0 (a)
             22 LOAD_CONST               4 ('test2')
             25 STORE_SUBSCR        

  5          26 LOAD_CONST               5 (12457)
             29 LOAD_FAST                0 (a)
             32 LOAD_CONST               6 ('test3')
             35 STORE_SUBSCR        
             36 LOAD_CONST               0 (None)
             39 RETURN_VALUE