尝试使用 itertools.permutations 时出现内存错误,如何使用更少的内存?

MemoryError while trying to using itertools.permutations, how use less memory?

我正在从一个包含随机字符串的文本文档中加载,我正在尝试打印该字符串中字符的所有可能排列。

如果记事本包含例如:

123
abc

我希望我的输出是

123,132,213,231,312,321
abc,acb,bac,bca,cab,cba

文本文件包含一些非常大的字符串,所以我可以理解为什么会出现此 MemoryError。

我第一次尝试使用这个:

import sys
import itertools
import math

def organize(to_print):
    number_list = []
    upper_list = []
    lower_list = []
    for x in range(0,len(to_print)):
        if str(to_print[x]).isdigit() is True:
            number_list.append(to_print[x])
        elif to_print[x].isupper() is True:
            upper_list.append(to_print[x])
        else:
            lower_list.append(to_print[x])
    master_list = number_list + upper_list + lower_list
    return master_list

number = open(*file_dir*, 'r').readlines()

factorial = math.factorial(len(number))
complete_series = ''

for x in range(0,factorial):
    complete_string = ''.join((list(itertools.permutations(organize(number)))[x]))

    complete_series += complete_string+','
edit_series = complete_series[:-1]
print(edit_series)

def organize 的原因是如果我有一个字符串 1aB 我需要在开始排列之前按数字、大写、小写对其进行预排序。

我在这里遇到内存错误:complete_string = ''.join((list(itertools.permutations(organize(number)))[x])) 所以我最初的尝试是将其从 for 循环中取出。


我的第二次尝试是这样的:

import sys
import itertools
import math

def organize(to_print):
    number_list = []
    upper_list = []
    lower_list = []
    for x in range(0,len(to_print)):
        if str(to_print[x]).isdigit() is True:
            number_list.append(to_print[x])
        elif to_print[x].isupper() is True:
            upper_list.append(to_print[x])
        else:
            lower_list.append(to_print[x])
    master_list = number_list + upper_list + lower_list
    return master_list

number = open(*file_dir*, 'r').readlines()

factorial = math.factorial(len(number))
complete_series = ''
the_permutation = list(itertools.permutations(organize(number)))

for x in range(0,factorial):
    complete_string = ''.join((the_permutation[x]))

    complete_series += complete_string+','
edit_series = complete_series[:-1]
print(edit_series)

但我仍然遇到内存错误。我不一定需要或直接想要答案,因为这是减少我效率低下的良好学习实践,所以正确方向的提示会很好。


添加了第三次尝试:

import sys
import itertools
import math

def organize(to_print):
    number_list = []
    upper_list = []
    lower_list = []
    for x in range(0,len(to_print)):
        if str(to_print[x]).isdigit() is True:
            number_list.append(to_print[x])
        elif to_print[x].isupper() is True:
            upper_list.append(to_print[x])
        else:
            lower_list.append(to_print[x])
    master_list = number_list + upper_list + lower_list
    return master_list

number = open(*file_dir*, 'r').readlines()

factorial = math.factorial(len(number))
complete_series = ''
the_permutation = itertools.permutations(organize(number))
for x in itertools.islice(the_permutation,factorial):
    complete_string = ''.join(next(the_permutation))
    complete_series += complete_string+','
edit_series = complete_series[:-1]
print(edit_series)

不要调用列表,只需迭代排列:

the_permutation = itertools.permutations(organize(number))

for x in the_permutation:
    complete_string = ''.join(the_permutation)

list(itertools.permutations(organize(number))) 将所有排列存储在内存中,然后将所有排列存储在循环中的字符串中,不能保证即使使用这种方法也能存储所有数据,具体取决于如何the_permutation

中有很多数据

如果您只想要一定数量的排列,您可以调用 next om 排列对象:

the_permutation = itertools.permutations(organize(number))
for x in range(factorial):
    complete_string = ''.join(next(the_permutation))

或使用itertools.islice:

for x in itertools.islice(the_permutation,factorial):
    complete_string = ''.join(next(the_permutation))

请记住阶乘增长非常快

... 所以即使是中等长度的字符串,排列的数量也是巨大的。 12 个字母大约 4.8 亿。