Reputation: 351
I'm loading from a text document containing so random strings and I'm trying to print every possible permutation of the characters in that string.
If the notepad contains for example:
123
abc
I want my output to be
123,132,213,231,312,321
abc,acb,bac,bca,cab,cba
The text file contains some pretty large strings so I can see why I am getting this MemoryError.
My first attempt I used this:
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)
The reason for def organize
is if I have a string 1aB
I would need to preorder it by number,uppercase,lowercase before I start the permutations.
I got the memory error here: complete_string = ''.join((list(itertools.permutations(organize(number)))[x]))
so my initial attempt was to bring it out of the for-loop.
My second attempt is this:
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)
But I am still getting a memory error. I don't necessarily need or want the answer directly as this is good learning practice to reduce my inefficiencies, so hints in the right direction would be nice.
Added 3rd attempt:
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)
Upvotes: 1
Views: 2297
Reputation: 180441
Don't call list, just iterate over the permutations:
the_permutation = itertools.permutations(organize(number))
for x in the_permutation:
complete_string = ''.join(the_permutation)
list(itertools.permutations(organize(number)))
stores all the permutations in memory then you store all the permutations in a string in your loop, there is no guarantee that you will be able to store all the data even using this approach depending on how much data is in the_permutation
If you only want a certain amount of the permutations you can call next om the permutations object:
the_permutation = itertools.permutations(organize(number))
for x in range(factorial):
complete_string = ''.join(next(the_permutation))
Or use itertools.islice:
for x in itertools.islice(the_permutation,factorial):
complete_string = ''.join(next(the_permutation))
Upvotes: 4
Reputation: 362
Keep in mind factorials grow enormously fast
... so even for a string of moderate length the number of permutations is enormous. For 12 letters its ~ 480 million.
Upvotes: 1