2017-02-07 19 views
2

Я создал функцию, которая генерирует непрерывный список алфавитов. A, B, C ..., Z. После Z он переходит в AA, AB, AC ... AZ. Эта картина повторяется. Это похоже на имена столбцов MS Excel. На данный момент эта функция генерирует конечный список алфавитов.Как создать бесконечный итератор для генерации инкрементирующего шаблона алфавита?

_column_name_generator() = ['A', 'B', ..., 'AA', 'AB', ..., 'BA', 'BB', ..., 'CV'] 

Я могу затем перебрать его в сочетании с некоторым конечным списком, например. 0-10. См. Мой код ниже. Я хотел бы создать генератор, который даст мне бесконечно длинный список инкрементирующих алфавитов.

import string 


def _column_name_generator(): 
    column_names = [] 
    for x in range(0, 100): 
     if x < 26: 
      column_names.append(string.ascii_uppercase[x % 26]) 
     else: 
      column_names.append(column_names[x/26 - 1] + string.ascii_uppercase[x % 26]) 
    return column_names 

container = [] 
for column_name, num in zip(_column_name_generator(), range(0, 10)): 
    container.append(column_name + str(num)) 

print _column_name_generator() 
print container 

container = ['A0', 'B1', 'C2', 'D3', 'E4', 'F5', 'G6', 'H7', 'I8', 'J9'] 
+0

исследуйте о' yield' –

ответ

6

Выход column_names «ы последнего элемента каждый раз, и использовать itertools.count вместо range, чтобы обеспечить бесконечное увеличение:

import itertools 

def _column_name_generator(): 
    column_names = [] 
    for x in itertools.count(): 
     if x < 26: 
      column_names.append(string.ascii_uppercase[x % 26]) 
     else: 
      column_names.append(column_names[x/26 - 1] + string.ascii_uppercase[x % 26]) 
     yield column_names[-1] 

А лучшее решение, изменяя исходный код, но об отказе в удовлетворении потребности в список использованной памяти column_names, будет

import itertools, string 

def _column_name_generator(): 
    for i in itertools.count(1): 
     for p in itertools.product(string.ascii_uppercase, repeat=i): 
      yield ''.join(p) 

он в основном выполняет итерацию над продуктом длины i заглавные буквы ascii (каждая последовательность возможна), когда i постепенно увеличивается, начиная с 1 (A, B, C).

+0

кажется немного тяжелым для поколения, чтобы сохранить список COLUMN_NAMES до тех пор, как количество yeilds – f5r5e5d

+0

@ f5r5e5d это правда! Как насчет добавления чего-то типа 'column_names = column_names [-26:]' в конце, чтобы сократить список вниз. Мысли? – bluprince13

+0

@ bluprince13 Я пытался сохранить код как можно ближе к оригиналу; Сегодня я отправлю метод потребления памяти без памяти – Uriel

1

Менее вещий способ

Как следует в вашем вопросе, один путь деления на 26 преобразующего остаток в письме на каждом шагу, до возвращения деления 0. Использование % (по модулю), чтобы получить остаток, // (floor division), чтобы обновить значение для следующего шага. Это может быть код:

numberOfElements = 100 
letters = [] 
for counter in range(numberOfElements): 
    i = counter 
    newCharacter = i % 26 
    i //= 26 
    s = "" +chr(newCharacter + ord('A')) 
    while i != 0: 
     newCharacter = i % 26 
     i //= 26 
     s = chr(newCharacter + ord('A')) + s 
    letters.append(s) 
print letters 

Результат:

[ '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 ',' BA ', ' BB ',' BC ',' BD ',' BE ',' BF «B», «B», «BJ», «BK», «BL», «BM», «BN», «BO», «BP», «BQ», «BR», , 'BS', 'BT', 'BU', 'BV', 'BW', 'BX', 'BY', 'BZ', 'CA', 'CB', 'CC', 'CD', ' 'CE', 'CF', 'CG', 'CH', 'CI', 'CJ', 'CK', ​​'CL', 'CM', 'CN', 'CO', 'CP', ' CQ ',' CR ',' CS ', 'CT', 'CU', 'CV', 'CW', 'CX', 'CY', 'CZ', 'DA', 'DB', 'DC', 'DD', 'DE', ' «DF», «DG», «DH», «DI», «DJ», «DK», «DL», «DM», «DN», «DO», «DP», «DQ», DR», 'DS', 'DT', 'DU', 'DV']

+2

Версия Python 3 будет приятной ...:) Другие вещи, которые вы могли бы сделать: поместите их в генератор, позвольте вызывающему указать верхний или нижний регистр, позвольте вызывающему указать начальную точку последовательности. –