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

Posted

技术标签:

【中文标题】尝试使用 itertools.permutations 时出现 MemoryError,如何使用更少的内存?【英文标题】:MemoryError while trying to using itertools.permutations, how use less memory? 【发布时间】:2015-07-08 20:59:01 【问题描述】:

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

如果记事本包含例如:

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)

【问题讨论】:

您正在将所有可能的排列组合成一个列表。你确定你需要随机访问所有可能的排列吗? 我认为排列的数量比你想象的要大一些。假设您有 1 个 a4 文本。然后在所有排列中,所有可能的英文,德文和法文诗歌都曾经写过...... 【参考方案1】:

不要调用列表,只需遍历排列:

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))

【讨论】:

我在考虑列表可能是问题之前尝试了这个,这是我的错误:Traceback (most recent call last): File "question.py", line 27, in <module> complete_string = ''.join(the_permutation) TypeError: sequence item 0: expected str instance, tuple found 不过我会尝试看看我可以去哪里。 那是因为你正在尝试加入元组,迭代然后加入每个元组与在排列对象上调用 join 不同 如果我得到这个是什么意思? Stop argument for islice() must be None or an integer: 0 <= x <= sys.maxsize. 我假设 int 太大,islice() 在这种情况下无法支持它? @AndyWong,很可能是的,什么是阶乘? 是的,您肯定需要以某种方式分解排列,但又取决于输入的大小有多大,因此不能保证它会起作用。【参考方案2】:

请记住,阶乘增长非常快

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

【讨论】:

以上是关于尝试使用 itertools.permutations 时出现 MemoryError,如何使用更少的内存?的主要内容,如果未能解决你的问题,请参考以下文章

尝试使用堆叠小部件构建布局

尝试使用 Curl 登录网站

不安全的 JavaScript 尝试使用框架访问

当我尝试使用 ansible ping 我的 VM 时,它会尝试 ping 服务器 ID 而不是 IP

尝试使用 ConfigurationBuilder 但得到 FileLoadException

尝试使用 Jquery 更改 HTML [重复]