如何在python3中节省内存?

alo*_*dev -2 python python-itertools python-3.x

我对python3.6中的内存错误有一些疑问

import itertools
input_list = ['a','b','c','d']
group_to_find = list(itertools.product(input_list,input_list))
a = []
for i in range(len(group_to_find)):
    if group_to_find[i] not in a:
       a.append(group_to_find[i])
Run Code Online (Sandbox Code Playgroud)
    group_to_find = list(itertools.product(input_list,input_list))
MemoryError
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 5

您正在从输入列表的笛卡尔积完全创建一个列表,因此,除了input_list您现在还需要len(input_list) ** 2用于所有结果的内存插槽。然后,您再次将该列表过滤为第4个列表。总而言之,对于N个项目,您需要2N +(N * N)个引用的内存。如果N为1000,则为100万和2000个引用,对于N = 1百万,则需要1亿加上200万个引用。等等。

您的代码根本不需要创建group_to_find列表,有两个原因:

  1. 您可以单独迭代和处理每对:

    a = []
    for pair in itertools.product(input_list, repeat=2):
        if pair not in a:
            a.append(pair)
    
    Run Code Online (Sandbox Code Playgroud)

    这仍然会很,因为pair not in a必须扫描整个列表以找到匹配项。您N最多可以进行两次K(其中K是中的唯一值数量的乘积input_list,可能等于N),因此这是N * K用于检查重复项的时间。您可以使用它a = set()来加快速度。但请参阅第2点。

  2. 除非输入的值不是唯一的,否则您输入的最终产品aitertools.product()无论如何都会产生的对完全相同的列表。您可以先使这些独特:

    a = itertools.product(set(input_list), repeat=2)
    
    Run Code Online (Sandbox Code Playgroud)

    同样,不要将其放在列表中。循环迭代并使用一对一产生的对。