Есть ли выражение для бесконечного генератора?


есть ли прямое выражение генератора, которое может давать бесконечные элементы?

Это чисто теоретический вопрос. Нет необходимости в "практическом" ответе здесь:)


например, легко сделать конечный генератор:

my_gen = (0 for i in xrange(42))

однако, чтобы сделать бесконечный, мне нужно "загрязнить" мое пространство имен фиктивной функцией:

def _my_gen():
    while True:
        yield 0
my_gen = _my_gen()

делать вещи в отдельном файле и import - ing позже не делает рассчитывать.


Я тоже это знаю itertools.repeat делает именно это. Мне любопытно, есть ли однострочное решение без этого.

8 83

8 ответов:

for x in iter(int, 1): pass
  • два-аргумент iter = вызываемый с нулевым аргументом + значение sentinel
  • int() всегда возвращает 0

таким образом, iter(int, 1) это бесконечный итератор. Очевидно, что существует огромное количество вариаций на эту тему (особенно после добавления lambda в смеси). Одним из вариантов особого Примечания является iter(f, object()), так как использование только что созданного объекта в качестве значения sentinel почти гарантирует бесконечный итератор независимо от отзывной используется в качестве первого аргумента.

itertools обеспечивает три бесконечных генераторов:

Я не знаю других в стандартной библиотеке.


так как вы попросили один лайнер:

__import__("itertools").count()

вы можете перебирать вызываемый возвращающий константу всегда отличается от ITER () ' s sentinel

g1=iter(lambda:0,1)

ваша ОС может предоставить что-то, что может быть использовано в качестве бесконечного генератора. Например, на Linux

for i in (0 for x in open('/dev/urandom')):
    print i

очевидно, что это не так эффективно, как

for i in __import__('itertools').repeat(0)
    print i

нет, который не использует внутренне другой бесконечный итератор, определенный как класс / функция / генератор (не-выражение, функция с yield). Выражение генератора всегда извлекается из anoter iterable и не делает ничего, кроме фильтрации и сопоставления его элементов. Вы не можете перейти от конечных элементов к бесконечным только с map и filter необходимо while (или for это не заканчивается, что именно то, что мы не можем использовать только for и конечных итераторы.)

Общая информация: PEP 3142 внешне похоже, но при ближайшем рассмотрении кажется, что он все еще требует for предложение (так что нет (0 while True) для вас), т. е. только обеспечивает ярлык для itertools.takewhile.

может быть, вы могли бы использовать декораторы, как например:

def generator(first):
    def wrap(func):
        def seq():
            x = first
            while True:
                yield x
                x = func(x)
        return seq
    return wrap

использование (1):

@generator(0)
def blah(x):
    return x + 1

for i in blah():
    print i

использование (2)

for i in generator(0)(lambda x: x + 1)():
    print i

Я думаю, что это может быть улучшено, чтобы избавиться от этих уродливых (). Однако это зависит от сложности последовательности, которую вы хотите создать. Вообще говоря, если ваша последовательность может быть выражена с помощью функций, то вся сложность и синтаксический сахар генераторов могут быть скрыты внутри декоратора или декоратор-как функция.

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

{ print("Hello world") for _ in
    (lambda o: setattr(o, '__iter__', lambda x:x)
            or setattr(o, '__next__', lambda x:True)
            or o)
    (type("EvilIterator", (object,), {}))() } 

(Как уже упоминалось, благодаря документации python https://docs.python.org/2/library/itertools.html#itertools.cycle)

def iter_cycle(iterator):
    saved = []
    for iterable in iterator:
        yield iterable
        saved.append(iterable)
    while saved:
        for element in saved:
              yield element

a = iter_cycle(iter([1,2,3]))

next (a) - > 1 далее(a) - > 2 далее (a) - > 3

далее (a) - > 1