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

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

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


Например, легко сделать конечную генерацию:

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

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

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

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


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

Ответ 1

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

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

Ответ 2

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

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


Поскольку вы попросили один-лайнер:

__import__("itertools").count()

Ответ 3

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

g1=iter(lambda:0,1)

Ответ 4

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

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

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

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

Ответ 5

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

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

Ответ 6

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

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

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

Ответ 7

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

{ 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,), {}))() } 

Ответ 8

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 следующий (а) → 2 next (a) → 3

next (a) → 1

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