如何避免Python中关于排列的记忆错误

如何避免Python中关于排列的记忆错误,python,permutation,itertools,Python,Permutation,Itertools,我正在编写一个简单的rar/zip破解程序。为了破解他们的密码,我准备了一个排列命令。但当我运行这些代码时: >>> import itertools >>> o = itertools.permutations("abcdefghijklmnoprstuvyzwxq1234567890_", 10) >>> a = list(o) 我得到了这个错误: Traceback (most recent call last): File "&

我正在编写一个简单的rar/zip破解程序。为了破解他们的密码,我准备了一个排列命令。但当我运行这些代码时:

>>> import itertools
>>> o = itertools.permutations("abcdefghijklmnoprstuvyzwxq1234567890_", 10)
>>> a = list(o)
我得到了这个错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
MemoryError
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
记忆者
UPD:

首先,如果您想从这个字母表中获取所有可能的密码,您应该使用
itertools
模块中的
product
函数,而不是
permutations

另外,如果要提高执行速度,应该使用
多处理
模块,而不是
线程

您可以通过这种方式实现您的目标,例如:

from itertools import product, islice
from multiprocessing import Pool

def crack(list_of_tuples):
    for letters in list_of_tuples:
        password = ''.join(letters)
        success = try_to_crack(password)
        if success:
            print('password is {}'.format(password))
            break

tuples = product('abcdefghijklmnoprstuvyzwxq1234567890_', repeat=10)

size_of_slice = 5000
number_of_processes = 8
running = True
while running:
    p = Pool(number_of_processes)
    slices = []
    for i in range(number_of_processes):
        l = list(islice(tuples, size_of_slice))
        if l:
            slices.append(l)
        else:
            running = False
    p.map(crack, slices)
另见

原始答案:

不要创建列表,只需按原样使用即可:

permutations = itertools.permutations("abcdefghijklmnoprstuvyzwxq1234567890_", 10)
for permutation in permutations:
    password = ''.join(permutation)
    success = try_to_crack(password)
    if success:
        print('password is {}'.format(password))
        break
不要创建排列的“列表”。 “置换”调用是一种特殊的构造,tat一次将生成一个置换-其思想是您使用它,然后检索下一个值

当你这样做的时候

>>> a = list(o)
您希望在内存中一次性记录所有值—在这种情况下,这是不够的


作为旁注-如果你在特定的例子中一次生成一个排列,你不会耗尽内存,但是你、你的计算机、太阳系和整个宇宙都会耗尽时间,因为大约30个元素中10个元素的组合数量超出了天文数字。

在您的列表中,将有1264020397516800个长度为10的排列。将它们存储在内存中需要超过160 TB(假设每个排列占用128字节)。如果我没有弄错的话,每秒一百万个密码只需要40年。我希望宇宙仍然存在。@jsbueno我正试图通过“a=list(o)”命令使用排列作为列表。我必须通过“a=list(o)”命令来使用它。为什么您认为必须将它们用作列表?Python中迭代器的整个思想——它们已经存在了十多年了——正是为了避免同时在内存中存储所有元素。第二:如果每个组合只占用一个字节,即近百万千兆字节,那么这个数量的排列将不适合内存—我们这里讨论的是922393263052800个组合。再一次-如果你真的使用了
排列
作为一个生成器,你就不会有内存问题,但是,尽管如此,我关于宇宙持续时间的笑话是分开的,你需要几十年的时间来检查它们。我知道这一点。但是,我试图通过“a=list(o)”命令使用排列作为列表。@python\u pardus为什么?你想用这个列表做什么?为了快速破解密码,我必须划分排列列表并分别发送线程。我的意思是:谢谢。。但我不明白为什么要给变量的数量给8?池函数中的数字(池(进程的数量))发生了什么变化?我的意思是,如果我们在池函数中给7个值,会有什么变化?当我尝试代码时,我得到了一个错误:“AttributeError:\u exit.\u”