0

Я написал функцию генератора, которая дает бесконечную последовательность строк в том же образом, как и в колонке именования схемы в приложении электронной таблицы, как Excel, например:Как эта функция генератора может быть преобразована в выражение генератора?

'', 'A', 'B', ... 'Z', 'AA', 'AB', ... 'AZ', 'BA', ... 'ZZ', 'AAA', ... 

Моя функция работает без каких-либо проблем:

def __suffix_generator(): 
    len, gen = (0, iter([''])) 

    while True: 
     try: 
      suffix = next(gen) 
     except StopIteration: 
      len += 1 
      gen = itertools.product(string.ascii_uppercase, repeat=len) 
      suffix = next(gen) 

     yield ''.join(suffix) 

Однако, я хочу, чтобы превратить его в более идиоматическую версию, которая будет использовать выражения только генератор и мой лучший снимок до сих пор это:

def __suffix_generator_gexp(): 
    from itertools import product, count 
    from string import ascii_uppercase 

    return (''.join(suffix) for suffix in 
     (product(ascii_uppercase, repeat=len) for len in count())) 

При использовании этого генератора, я получаю во время выполнения TypeError, который говорит мне, что тип переменной suffix не принят:

TypeError: sequence item 0: expected string, tuple found 

Мое предположение, что suffix должен быть кортежем, содержащие буквы конкретной комбинации и что join превратит это в строку. Как я могу заставить это работать правильно, как первая функция?

+1

'join' присоединяется к кортежу строк в строку. Ошибка говорит, что 'suffix [0]' является кортежем, а не строкой, – khelwood

+2

FWIW. Плохая практика назначать значения встроенным. 'len' является встроенной функцией в Python, и вы заменяете ее в пределах этой функции, когда вы назначаете' 0' 'len'. Вместо этого предпочтительным может быть использование чего-то типа 'length', но близкое к логике, которую вы пытаетесь передать с помощью' len' в настоящее время. – blacksite

+0

@not_a_robot: спасибо, это мои первые попытки с Python, и я даже не подозревал, что существует встроенный 'len'. –

ответ

2

Может быть, это то, что вы ищете:

map(''.join, chain.from_iterable(product(ascii_uppercase, repeat=l) for l in count(1))) 

count(n) производит последовательность чисел, начиная с n использованием step = 1, так что каждое число N_{t+1} = N_t + step и N_1 = n.

Если вы используете Python 2.x, map будет пытаться построить список и не получится, так что вы можете просто сделать:

(''.join(perm) for perm in (...)) 

Где ... является вторым аргументом map из первого фрагмента кода ,

+1

Спасибо! Второй фрагмент отлично работал в Python 2.7.13. –