Используя itertools
, находит те же 239200 строк, что и у @ ggorlen.
from string import ascii_uppercase
from itertools import combinations, product
def all_alphabetical_pw(length):
for c in combinations(ascii_uppercase, length):
for p in product(*zip(c, map(str.lower, c))):
yield ''.join(p)
И вариант, не уверен, какой мне больше нравится:
def all_alphabetical_pw(length):
for c in combinations(zip(ascii_uppercase, ascii_lowercase), length):
for p in product(*c):
yield ''.join(p)
Обе работают по производит комбинаций , таких как (('D', 'd'), ('I', 'i'), ('N', 'n'), ('O', 'o'))
, а затем их продуктов , давая кортежи, подобные ('D', 'i', 'n', 'O')
, которые просто необходимо объединить. Эти два решения отличаются только тем, что я превращаю буквы типа 'D'
в пары типа ('D', 'd')
.
Первая версия делает это после , получая комбинации типа ('D', 'I', 'N', 'O')
, превращая каждую такую комбинацию в комбинацию (верхняя, нижняя) пар.
Вторая версия делает это до , создавая комбинации, вместо этого создавая пары для всего алфавита один раз. Это более эффективно и выглядит чище. Хорошо, я предпочитаю это сейчас.
Тесты:
@ggorlen's 0.199 seconds
my first 0.094 seconds
my second 0.072 seconds
Измеряется так:
timeit(lambda: list(all_alphabetical_pw(4)), number=100) / 100
О, еще один. Занимает 0,056 секунды, поэтому он самый быстрый, но мне он нравится меньше:
def all_alphabetical_pw(length):
for c in combinations(zip(ascii_uppercase, ascii_lowercase), length):
yield from map(''.join, product(*c))