I\'m trying to create a loop to generate and print strings as follows:
I coded this today. It does exactly what you want and more. It's extendable as well
def lastCase (lst):
for i in range(0, len(lst)):
if ( lst[i] != '_' ):
return False
return True
l = [''] * 4 #change size here if needed. I used 4
l[0] = '0'
index = 0
while ( not lastCase(l) ):
if ( ord(l[index]) > ord('_') ):
l[index] = '0'
index += 1
while( l[index] == '_' ):
l[index] = '0'
index += 1
if (l[index] == ''):
l[index] = '0'
#print or process generated string
print(''.join(l))
l[index] = chr(ord(l[index]) +1)
if ( ord(l[index]) > ord('9') and ord(l[index]) < ord('A') ):
l[index] = 'A'
elif ( ord(l[index]) > ord('Z') and ord(l[index]) < ord('_') ):
l[index] = '_'
index = 0
print (''.join(l))
from string import digits, ascii_uppercase, ascii_lowercase
from itertools import product
chars = digits + ascii_uppercase + ascii_lowercase
def give_me_next(lst):
lst = lst[::-1]
change_next = False
change = True
n = 0
for x in lst:
if change_next == True:
change_next = False
pos = chars.find(x)
try:
a = chars[pos+1]
lst = list(lst)
lst[n] = a
lst = "".join(lst)
x = a
except:
lst = list(lst)
lst[n] = '0'
lst = "".join(lst)
change_next = True
x = '0'
pos = chars.find(x)
try:
a = chars[pos+1]
if change == True:
lst = list(lst)
lst[n] = a
lst = "".join(lst)
change = False
except:
lst = list(lst)
lst[n] = '0'
lst = "".join(lst)
change_next = True
n = n + 1
lst = lst[::-1]
return lst
a= give_me_next('zzzzz')
while True:
a = give_me_next(a)
print a
I dislike the answer given before me using product since looking at its implementation in the python documentation it seem to span the entire thing into a list in memory before starting to yield the results.
This is very bad for your case since, as agf himself said, the number of permutation here is huge (well over a million). For this case the yield statement was created - so that huge lists could be dynamically generated rather than spanned in memory (I also disliked the wasteful range where xrange is perfectly applicable).
I'd go for a solution like this:
def generate(chars, length, prefix = None):
if length < 1:
return
if not prefix:
prefix = ''
for char in chars:
permutation = prefix + char
if length == 1:
yield permutation
else:
for sub_permutation in generate(chars, length - 1, prefix = permutation):
yield sub_permutation
This way, all that spans in memory is a recursive stack "n" deep, where "n" is the length of your permutations (4 in this case) and only a single element is returned each time.
chars is the set of chars to choose from, length is 4 and the use is rather similar to products, except that it doesn't span the whole list in memory during run time.
from string import digits, ascii_uppercase, ascii_lowercase
from itertools import product
chars = digits + ascii_uppercase + ascii_lowercase
for n in range(1, 4 + 1):
for comb in product(chars, repeat=n):
print ''.join(comb)
This first makes a string of all the numbers, uppercase letters, and lowercase letters.
Then, for each length from 1-4, it prints every possible combination of those numbers and letters.
Keep in mind this is A LOT of combinations -- 62^4 + 62^3 + 62^2 + 62.
This seems like the simplest solution to me:
from string import digits, ascii_uppercase, ascii_lowercase
chars = digits + ascii_uppercase + ascii_lowercase
all_str = [''.join([a]) for a in chars] \
+ [''.join([a,b]) for a in chars for b in chars] \
+ [''.join([a,b,c]) for a in chars for b in chars for c in chars] \
+ [''.join([a,b,c,d]) for a in chars for b in chars for c in chars for d in chars]
print(all_str)
print("Number of strings:", len(all_str))
Example for strings with maximum 2 characters.
Of course, there may be a way to generalize to any max number of characters per string, but since you have a specific need for strings up to 4 characters, it's fine.