Генерация буквенно-цифровых строк последовательно - PullRequest
8 голосов
/ 20 августа 2011

Я пытаюсь создать цикл для генерации и печати строк следующим образом:

  1. Только буквенно-цифровые символы:
  2. 0-9 перед A-Z, перед a-z,
  3. Длина до 4 символов.

Таким образом, это напечатало бы:

  1. все строки из 0-z
  2. затем от 00-zz
  3. затем от 000-zzz
  4. затем от 0000-zzzz

затем он останавливается.

Ответы [ 5 ]

23 голосов
/ 20 августа 2011
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)

Сначала создается строка из всех цифр, заглавных и строчных букв.

Затем для каждой длины от 1 до 4 он печатает все возможные комбинации этих цифр и букв.

Имейте в виду, что это много комбинаций - 62 ^ 4 + 62 ^ 3 + 62 ^ 2 + 62.

0 голосов
/ 02 октября 2018

Мне кажется, это самое простое решение:

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

Пример для строк длиной не более 2 символов.

Конечно, может быть способобобщите до любого максимального количества символов в строке, но, так как у вас есть конкретная потребность в строках длиной до 4 символов, это нормально.

0 голосов
/ 25 июня 2018
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
0 голосов
/ 16 августа 2014

Я кодировал это сегодня.Он делает именно то, что вы хотите и более .Это также расширяемый

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))
0 голосов
/ 20 августа 2011

Мне не нравится ответ, данный передо мной с использованием product, так как, глядя на его реализацию в документации по python, кажется, что все это заносится в список в памяти, прежде чем начать давать результаты.

Это очень плохо для вашего случая, поскольку, как сказал сам Агф, число перестановок здесь огромно (более миллиона). Для этого случая был создан оператор yield, чтобы огромные списки могли генерироваться динамически, а не охватываться в памяти (я также не любил расточительный range, где xrange совершенно применимо).

Я бы пошел к решению, как это:

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

Таким образом, все, что охватывает память, представляет собой рекурсивный стек «n» в глубине, где «n» - это длина ваших перестановок (в данном случае 4), и каждый раз возвращается только один элемент.

chars - набор символов для выбора, длина - 4, и использование довольно похоже на продукты, за исключением того, что оно не охватывает весь список в памяти во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...