I want to create alphabetically ascending names like the column names in excel. That is I want to have smth. like a,b,c,...,z,aa,ab,...az,...zz,aaa,aab,....
I have tried:
for i in range(1000):
mod = int(i%26)
div = int(i/26)
print(string.ascii_lowercase[div]+string.ascii_lowercase[mod])
Which works until zz but than fails because it runs out of index
aa
ab
ac
ad
ae
af
ag
ah
ai
aj
ak
al
.
.
.
zz
IndexError
You could make use of itertools.product():
from itertools import product
from string import ascii_lowercase
for i in range(1, 4):
for x in product(ascii_lowercase, repeat=i):
print(''.join(x))
First, you want all letters, then all pairs, then all triplets, etc. This is why we first need to iterate through all the string lengths you want (for i in range(...)).
Then, we need all possible associations with the i letters, so we can use product(ascii_lowercase) which is equivalent to a nested for loop repeated i times.
This will generate the tuples of size i required, finally just join() them to obtain a string.
To continuously generate names without limit, replace the for loop with while:
def generate():
i = 0
while True:
i += 1
for x in product(ascii_lowercase, repeat=i):
yield ''.join(x)
generator = generate()
next(generator) # 'a'
next(generator) # 'b'
...
For a general solution we can use a generator and islice from itertools:
import string
from itertools import islice
def generate():
base = ['']
while True:
next_base = []
for b in base:
for i in range(26):
next_base.append(b + string.ascii_lowercase[i])
yield next_base[-1]
base = next_base
print('\n'.join(islice(generate(), 1000)))
And the output:
a
b
c
...
z
aa
ab
...
zz
aaa
aab
...
And you can use islice to take as many strings as you need.
Try:
>>import string
>>string.ascii_lowercase
'abcdefghijklmnopqrstuvwxyz'
>>len(string.ascii_lowercase)
26
When your index in below line exceed 26 it raise exception
div = int(i/26)
, becouse of ascii_lowercase length:
But you can:
for i in range(26*26): # <--- 26 is string.ascii_lowercase
mod = int(i%26)
div = int(i/26)
print(string.ascii_lowercase[div]+string.ascii_lowercase[mod])
EDIT:
or you can use:
import string
n = 4 # number of chars
small_limit = len(string.ascii_lowercase)
limit = small_limit ** n
i = 0
while i < limit:
s = ''
for c in range(n):
index = int(i/(small_limit**c))%small_limit
s += string.ascii_lowercase[index]
print(s)
i += 1
You can use:
from string import ascii_lowercase
l = list(ascii_lowercase) + [letter1+letter2 for letter1 in ascii_lowercase for letter2 in ascii_lowercase]+ [letter1+letter2+letter3 for letter1 in ascii_lowercase for letter2 in ascii_lowercase for letter3 in ascii_lowercase]
There's an answer to this question provided on Code Review SE
A slight modification to the answer in the link gives the following which works for an arbitrary number of iterations.
def increment_char(c):
return chr(ord(c) + 1) if c != 'z' else 'a'
def increment_str(s):
lpart = s.rstrip('z')
num_replacements = len(s) - len(lpart)
new_s = lpart[:-1] + increment_char(lpart[-1]) if lpart else 'a'
new_s += 'a' * num_replacements
return new_s
s = ''
for _ in range(1000):
s = increment_str(s)
print(s)
Related
I would like to make a alphabetical list for an application similar to an excel worksheet.
A user would input number of cells and I would like to generate list.
For example a user needs 54 cells. Then I would generate
'a','b','c',...,'z','aa','ab','ac',...,'az', 'ba','bb'
I can generate the list from [ref]
from string import ascii_lowercase
L = list(ascii_lowercase)
How do i stitch it together?
A similar question for PHP has been asked here. Does some one have the python equivalent?
Use itertools.product.
from string import ascii_lowercase
import itertools
def iter_all_strings():
for size in itertools.count(1):
for s in itertools.product(ascii_lowercase, repeat=size):
yield "".join(s)
for s in iter_all_strings():
print(s)
if s == 'bb':
break
Result:
a
b
c
d
e
...
y
z
aa
ab
ac
...
ay
az
ba
bb
This has the added benefit of going well beyond two-letter combinations. If you need a million strings, it will happily give you three and four and five letter strings.
Bonus style tip: if you don't like having an explicit break inside the bottom loop, you can use islice to make the loop terminate on its own:
for s in itertools.islice(iter_all_strings(), 54):
print s
You can use a list comprehension.
from string import ascii_lowercase
L = list(ascii_lowercase) + [letter1+letter2 for letter1 in ascii_lowercase for letter2 in ascii_lowercase]
Following #Kevin 's answer :
from string import ascii_lowercase
import itertools
# define the generator itself
def iter_all_strings():
size = 1
while True:
for s in itertools.product(ascii_lowercase, repeat=size):
yield "".join(s)
size +=1
The code below enables one to generate strings, that can be used to generate unique labels for example.
# define the generator handler
gen = iter_all_strings()
def label_gen():
for s in gen:
return s
# call it whenever needed
print label_gen()
print label_gen()
print label_gen()
I've ended up doing my own.
I think it can create any number of letters.
def AA(n, s):
r = n % 26
r = r if r > 0 else 26
n = (n - r) / 26
s = chr(64 + r) + s
if n > 26:
s = AA(n, s)
elif n > 0:
s = chr(64 + n) + s
return s
n = quantity | r = remaining (26 letters A-Z) | s = string
To print the list :
def uprint(nc):
for x in range(1, nc + 1):
print AA(x,'').lower()
Used VBA before convert to python :
Function AA(n, s)
r = n Mod 26
r = IIf(r > 0, r, 26)
n = (n - r) / 26
s = Chr(64 + r) & s
If n > 26 Then
s = AA(n, s)
ElseIf n > 0 Then
s = Chr(64 + n) & s
End If
AA = s
End Function
Using neo's insight on a while loop.
For a given iterable with chars in ascending order. 'abcd...'.
n is the Nth position of the representation starting with 1 as the first position.
def char_label(n, chars):
indexes = []
while n:
residual = n % len(chars)
if residual == 0:
residual = len(chars)
indexes.append(residual)
n = (n - residual)
n = n // len(chars)
indexes.reverse()
label = ''
for i in indexes:
label += chars[i-1]
return label
Later you can print a list of the range n of the 'labels' you need using a for loop:
my_chrs = 'abc'
n = 15
for i in range(1, n+1):
print(char_label(i, my_chrs))
or build a list comprehension etc...
Print the set of xl cell range of lowercase and uppercase charterers
Upper_case:
from string import ascii_uppercase
import itertools
def iter_range_strings(start_colu):
for size in itertools.count(1):
for string in itertools.product(ascii_uppercase, repeat=size):
yield "".join(string)
input_colume_range = ['A', 'B']
input_row_range= [1,2]
for row in iter_range_strings(input_colume_range[0]):
for colum in range(int(input_row_range[0]), int(input_row_range[1]+1)):
print(str(row)+ str(colum))
if row == input_colume_range[1]:
break
Result:
A1
A2
B1
B2
In two lines (plus an import):
from string import ascii_uppercase as ABC
count = 100
ABC+=' '
[(ABC[x[0]] + ABC[x[1]]).strip() for i in range(count) if (x:= divmod(i-26, 26))]
Wrap it in a function/lambda if you need to reuse.
code:
alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
for i in range(len(alphabet)):
for a in range(len(alphabet)):
print(alphabet[i] + alphabet[a])
result:
aa
ab
ac
ad
ae
af
ag
ah
ai
aj
ak
al
am
...
I'm trying to create a wordlist generator that creates a file with all possible combinations of uppercase letters and numbers but in this very specific format:
AAA00AA (uppercase, uppercase, uppercase, digit, digit, uppercase, uppercase)
So the first string would be AAA00AA and the last one ZZZ99ZZ.
There are over 1 billion possible combinations and I'm using the itertools.product function.
However, I'm stuck on how to loop through the results of each iteration in order to get each group (AAA 00 AA) to combine among themselves. Here's what I got so far, but each loop runs just once. For example when the first group AAA 00 AA reaches ZZZ 00 AA I then need to get the second group through 1 iteration to AAA 01 AA and so on until the third group.
I'm sure that my loop nesting logic is wrong or perhaps I need to use some other approach, but I have no idea what to do. Can anyone help, please? Here's my code so far.
import string
import itertools
import datetime
letters = string.ascii_uppercase
digits = string.digits
first_group = itertools.product(letters, repeat=3)
second_group = itertools.product(digits, repeat=2)
third_group = itertools.product(letters, repeat=2)
FILE = open("mylist.txt","w")
start = datetime.datetime.now()
for i in first_group:
first = ''.join(i)
FILE.write(first + '\n')
for a in second_group:
second = first +''.join(a)
FILE.write(second + '\n')
for x in third_group:
string = second +''.join(x)
FILE.write(string + '\n')
string = ''
FILE.close()
print 'DONE! - Finished in %s' % (datetime.datetime.now() - start)
You can use itertools.product to join the sub products again.
f, s, t = [
itertools.product(d, repeat=r)
for d, r in zip([letters, digits, letters], [3, 2, 2])
]
with open("mylist.txt", "w") as f:
for prod in itertools.product(f, s, t):
string = ''.join([''.join(k) for k in prod])
f.write(string + '\n')
# AAA00AA
# AAA00AB
# AAA00AC
# AAA00BA
# AAA00BB
# .......
import string
import itertools
import datetime
letters = string.ascii_uppercase
digits = string.digits
first_group = itertools.product(letters, repeat=3)
second_group = itertools.product(digits, repeat=2)
third_group = itertools.product(letters, repeat=2)
start = datetime.datetime.now()
with open("mylist.txt","w") as FILE:
for i in first_group:
first = ''.join(i)
for j in second_group:
second = ''.join(j)
for k in third_group:
FILE.write(first + second + ''.join(k) + '\n')
print 'DONE! - Finished in %s' % (datetime.datetime.now() - start)
Generates:
AAA00AA
AAA00AB
AAA00AC
AAA00AD
AAA00AE
AAA00AF
...
Everything else you can leave as they are. the itertools.product solution by #Coldspeed is however more elegant and probably faster too. I just wanted to correct your code.
Use a list comprehension:
res = ["".join(itertools.chain(a,b,c)) for c in third_group for b in second_group for a in first_group]
res
['AAA00AA', 'AAB00AA', 'AAC00AA', 'AAD00AA', 'AAE00AA', 'AAF00AA', 'AAG00AA', 'AAH00AA', 'AAI00AA', 'AAJ00AA', 'AAK00AA', 'AAL00AA', 'AAM00AA', 'AAN00AA', 'AAO00AA', 'AAP00AA', 'AAQ00AA', 'AAR00AA', 'AAS00AA', 'AAT00AA', 'AAU00AA', 'AAV00AA', 'AAW00AA', 'AAX00AA', 'AAY00AA',...]
You can even make it a generator object:
for e in ("".join(itertools.chain(a,b,c)) for c in third_group for b in second_group for a in first_group):
print e
I would like to make a alphabetical list for an application similar to an excel worksheet.
A user would input number of cells and I would like to generate list.
For example a user needs 54 cells. Then I would generate
'a','b','c',...,'z','aa','ab','ac',...,'az', 'ba','bb'
I can generate the list from [ref]
from string import ascii_lowercase
L = list(ascii_lowercase)
How do i stitch it together?
A similar question for PHP has been asked here. Does some one have the python equivalent?
Use itertools.product.
from string import ascii_lowercase
import itertools
def iter_all_strings():
for size in itertools.count(1):
for s in itertools.product(ascii_lowercase, repeat=size):
yield "".join(s)
for s in iter_all_strings():
print(s)
if s == 'bb':
break
Result:
a
b
c
d
e
...
y
z
aa
ab
ac
...
ay
az
ba
bb
This has the added benefit of going well beyond two-letter combinations. If you need a million strings, it will happily give you three and four and five letter strings.
Bonus style tip: if you don't like having an explicit break inside the bottom loop, you can use islice to make the loop terminate on its own:
for s in itertools.islice(iter_all_strings(), 54):
print s
You can use a list comprehension.
from string import ascii_lowercase
L = list(ascii_lowercase) + [letter1+letter2 for letter1 in ascii_lowercase for letter2 in ascii_lowercase]
Following #Kevin 's answer :
from string import ascii_lowercase
import itertools
# define the generator itself
def iter_all_strings():
size = 1
while True:
for s in itertools.product(ascii_lowercase, repeat=size):
yield "".join(s)
size +=1
The code below enables one to generate strings, that can be used to generate unique labels for example.
# define the generator handler
gen = iter_all_strings()
def label_gen():
for s in gen:
return s
# call it whenever needed
print label_gen()
print label_gen()
print label_gen()
I've ended up doing my own.
I think it can create any number of letters.
def AA(n, s):
r = n % 26
r = r if r > 0 else 26
n = (n - r) / 26
s = chr(64 + r) + s
if n > 26:
s = AA(n, s)
elif n > 0:
s = chr(64 + n) + s
return s
n = quantity | r = remaining (26 letters A-Z) | s = string
To print the list :
def uprint(nc):
for x in range(1, nc + 1):
print AA(x,'').lower()
Used VBA before convert to python :
Function AA(n, s)
r = n Mod 26
r = IIf(r > 0, r, 26)
n = (n - r) / 26
s = Chr(64 + r) & s
If n > 26 Then
s = AA(n, s)
ElseIf n > 0 Then
s = Chr(64 + n) & s
End If
AA = s
End Function
Using neo's insight on a while loop.
For a given iterable with chars in ascending order. 'abcd...'.
n is the Nth position of the representation starting with 1 as the first position.
def char_label(n, chars):
indexes = []
while n:
residual = n % len(chars)
if residual == 0:
residual = len(chars)
indexes.append(residual)
n = (n - residual)
n = n // len(chars)
indexes.reverse()
label = ''
for i in indexes:
label += chars[i-1]
return label
Later you can print a list of the range n of the 'labels' you need using a for loop:
my_chrs = 'abc'
n = 15
for i in range(1, n+1):
print(char_label(i, my_chrs))
or build a list comprehension etc...
Print the set of xl cell range of lowercase and uppercase charterers
Upper_case:
from string import ascii_uppercase
import itertools
def iter_range_strings(start_colu):
for size in itertools.count(1):
for string in itertools.product(ascii_uppercase, repeat=size):
yield "".join(string)
input_colume_range = ['A', 'B']
input_row_range= [1,2]
for row in iter_range_strings(input_colume_range[0]):
for colum in range(int(input_row_range[0]), int(input_row_range[1]+1)):
print(str(row)+ str(colum))
if row == input_colume_range[1]:
break
Result:
A1
A2
B1
B2
In two lines (plus an import):
from string import ascii_uppercase as ABC
count = 100
ABC+=' '
[(ABC[x[0]] + ABC[x[1]]).strip() for i in range(count) if (x:= divmod(i-26, 26))]
Wrap it in a function/lambda if you need to reuse.
code:
alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
for i in range(len(alphabet)):
for a in range(len(alphabet)):
print(alphabet[i] + alphabet[a])
result:
aa
ab
ac
ad
ae
af
ag
ah
ai
aj
ak
al
am
...
I have a string:
'ABCDEFGH'
I want to cycle through the string and, one by one, replace each character with one of 4 characters (1,2,3,4):
'ABCDEFGH'
'1BCDEFGH'
'A1CDEFGH'
'AB1DEFGH'
etc
'2BCDEFGH'
'A2CDEFGH'
'AB2DEFGH'
etc and so forth. However everytime I try, I end up altering the original string and my output ends up being strings of 1s!
'1111111'
Example code below:
letters = 'ABCDEFGH'
s = list(letters)
y = 0
while y < len(s):
s[y] = '1'
y = y + 1
Rather than change a list you reuse between iterations, produce a new list each time and replace the one character:
for i in range(len(letters)):
s = list(letters)
s[i] = '1'
print(''.join(s))
You can combine this with a nested loop:
for digit in '1234':
for i in range(len(letters)):
s = list(letters)
s[i] = digit
print(''.join(s))
In essence you are creating the product of '1234' and a position from range(len(letters)), so you could use itertools.product() to make that a single loop:
from itertools import product
for digit, pos in product('1234', range(len(letters))):
s = list(letters)
s[pos] = digit
print(''.join(s))
With a little enumerate() trickery you could make this a one-liner generator expression to produce all combinations:
from itertools import product
all_combos = (
''.join([digit if i == pos else c for i, c in enumerate(letters)])
for digit, pos in product('1234', range(len(letters))))
This builds a new list on the fly by iteration over letters, swapping out the one character at position pos for the digit.
Demo:
>>> from itertools import product
>>> letters = 'ABCDEFGH'
>>> all_combos = (
... ''.join([digit if i == pos else c for i, c in enumerate(letters)])
... for digit, pos in product('1234', range(len(letters))))
>>>
>>> next(all_combos)
'1BCDEFGH'
>>> next(all_combos)
'A1CDEFGH'
>>> next(all_combos)
'AB1DEFGH'
>>> next(all_combos)
'ABC1EFGH'
>>> from itertools import islice
>>> print(list(islice(all_combos, 10)))
['ABCD1FGH', 'ABCDE1GH', 'ABCDEF1H', 'ABCDEFG1', '2BCDEFGH', 'A2CDEFGH', 'AB2DEFGH', 'ABC2EFGH', 'ABCD2FGH', 'ABCDE2GH']
Reinitialize the list each time.
while y < len(letters):
s = list(letters)
s[y] = '1'
y = y + 1
dosomethingwith(s)
string = 'ABCDEFG'
dig = []
for i in range(1,8):
dig.append(str(i))
for letter in string[:]:
print string.replace(letter,dig[i-1])
what's a simple way to increase the length of a string to an arbitrary integer x? like 'a' goes to 'z' and then goes to 'aa' to 'zz' to 'aaa', etc.
That should do the trick:
def iterate_strings(n):
if n <= 0:
yield ''
return
for c in string.ascii_lowercase:
for s in iterate_strings(n - 1):
yield c + s
It returns a generator.
You can iterate it with a for loop:
for s in iterate_strings(5)
Or get a list of the strings:
list(iterate_strings(5))
If you want to iterate over shorter strings too, you can use this function:
def iterate_strings(n):
yield ''
if n <= 0:
return
for c in string.ascii_lowercase:
for s in iterate_strings(n - 1):
yield c + s
Here's my solution, similar to Adam's, except it's not recursive. :].
from itertools import product
from string import lowercase
def letter_generator(limit):
for length in range(1, limit+1):
for letters in product(lowercase, repeat=length):
yield ''.join(letters)
And it returns a generator, so you can use a for loop to iterate over it:
for letters in letter_generator(5):
# ...
Have fun!
(This is the second time today I found itertools.product() useful. Woot.)
You can multiply the string in the integer.
For example
>>> 'a' * 2
'aa'
>>> 'a' * 4
'aaaa'
>>> 'z' * 3
'zzz'
>>> 'az' * 3
'azazaz'
Define x. I am using x = 5 for this example.
x = 5
import string
for n in range(1,x+1):
for letter in string.ascii_lowercase:
print letter*n