2015-07-08 4 views
1

Я загружаюсь из текстового документа, содержащего такие случайные строки, и я пытаюсь распечатать каждую возможную перестановку символов в этой строке.MemoryError при попытке использовать itertools.permutations, как использовать меньше памяти?

Если блокнот содержит, например:

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

Вы вносите все возможные перестановки в список. Вы уверены, что вам нужен случайный доступ ко всем возможным перестановкам? –

+0

Я думаю, что количество перестановок несколько больше, чем вы думаете. Предположим, у вас есть 1 a4 текста.Тогда среди всех перестановок есть все возможные стихи на английском, немецком и французском языках, которые когда-либо были написаны ... –

ответ

3

Не называйте список, просто перебирать перестановок:

the_permutation = itertools.permutations(organize(number)) 

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

list(itertools.permutations(organize(number))) хранит все перестановки в памяти, то вы сохраняете все перестановки в строке в вашем цикле нет гарантии, что вы сможете хранить все данные, даже используя этот подход, в зависимости от того, сколько данных находится в the_permutation

Если вы хотите только определенное количество перестановок можно вызвать следующим ом перестановок объекта:

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

Я пробовал это, прежде чем рассматривать список может быть проблемой, вот моя ошибка: 'Traceback (последний последний звонок): Файл "question.py", строка 27, в complete_string = '' .join (the_permutation) TypeError: последовательность пункт 0: ожидается ул экземпляра, кортеж found' Я постараюсь, чтобы увидеть, где я могу пойти с это все же. –

+0

Это связано с тем, что вы пытаетесь присоединиться к кортежам, итерация, а затем объединение каждого кортежа - это не то же самое, что вызов соединения в объекте перестановок. –

+0

Что это значит, если я получу это? 'Стоп-аргумент для islice() должен быть None или integer: 0 <= x <= sys.maxsize.' Я предполагаю, что int слишком велик для' islice() 'для поддержки в этом случае? –

0

Имейте в виде факториалах растет чрезвычайно быстро

enter image description here

. .. так что даже для строки умеренной длины количество перестановок огромно. За 12 писем его ~ 480 миллионов.

Смежные вопросы