Создать алфавитный возрастающий список - PullRequest
0 голосов
/ 22 ноября 2018

Я хочу создать алфавитно восходящие имена, такие как имена столбцов в Excel.То есть я хочу чего-л.как a, b, c, ..., z, aa, ab, ... az, ... zz, aaa, aab, ....

Я пробовал:

for i in range(1000):
    mod = int(i%26)
    div = int(i/26)
    print(string.ascii_lowercase[div]+string.ascii_lowercase[mod])

, который работает до zz , но затем не работает, потому что у него заканчивается индекс

aa
ab
ac
ad
ae
af
ag
ah
ai
aj
ak
al
.
.
.
zz

IndexError

Ответы [ 5 ]

0 голосов
/ 22 ноября 2018

Попробуйте:

>>import string
>>string.ascii_lowercase
'abcdefghijklmnopqrstuvwxyz'
>>len(string.ascii_lowercase)
26

Когда ваш индекс в нижней строке превышает 26, он вызывает исключение

div = int(i/26)

, так как длина ascii_lowercase:

Но вы можете:

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])

РЕДАКТИРОВАТЬ:

или вы можете использовать:

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
0 голосов
/ 22 ноября 2018

Ответ на этот вопрос приведен в Code Review SE

Небольшое изменение ответа в ссылке дает следующее, что работает для произвольного числа итераций.

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)
0 голосов
/ 22 ноября 2018

Для общего решения мы можем использовать генератор и islice из 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)))

И вывод:

a
b
c
...
z
aa
ab
...
zz
aaa
aab
...

И вы можетеиспользуйте islice, чтобы взять столько строк, сколько вам нужно.

0 голосов
/ 22 ноября 2018

Вы можете использовать:

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]
0 голосов
/ 22 ноября 2018

Вы можете использовать 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))

Сначала вы хотите получить все буквы, затем все пары, затем все триплеты и т. Д. Вот почему нам сначала нужнодля перебора всех длин строк, которые вы хотите (for i in range(...)).

Затем нам нужны все возможные ассоциации с i буквами, поэтому мы можем использовать product(ascii_lowercase), что эквивалентно вложенному for цикл повторяется i раз.

Это сгенерирует наборы нужного размера i, и, наконец, просто join() их, чтобы получить строку.

Чтобы непрерывно генерировать имена без ограничений,замените петлю for на 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'
...
...