Есть ли выражение для бесконечного генератора?
есть ли прямое выражение генератора, которое может давать бесконечные элементы?
Это чисто теоретический вопрос. Нет необходимости в "практическом" ответе здесь:)
например, легко сделать конечный генератор:
my_gen = (0 for i in xrange(42))
однако, чтобы сделать бесконечный, мне нужно "загрязнить" мое пространство имен фиктивной функцией:
def _my_gen():
while True:
yield 0
my_gen = _my_gen()
делать вещи в отдельном файле и import
- ing позже не делает рассчитывать.
Я тоже это знаю itertools.repeat
делает именно это. Мне любопытно, есть ли однострочное решение без этого.
8 ответов:
for x in iter(int, 1): pass
- два-аргумент
iter
= вызываемый с нулевым аргументом + значение sentinelint()
всегда возвращает0
таким образом,
iter(int, 1)
это бесконечный итератор. Очевидно, что существует огромное количество вариаций на эту тему (особенно после добавленияlambda
в смеси). Одним из вариантов особого Примечания являетсяiter(f, object())
, так как использование только что созданного объекта в качестве значения sentinel почти гарантирует бесконечный итератор независимо от отзывной используется в качестве первого аргумента.
itertools
обеспечивает три бесконечных генераторов:
count(start=0, step=1)
: 0, 1, 2, 3, 4, ...
cycle(p)
: p[0], p[1],..., p[-1], p[0],...
repeat(x, times=∞)
: x, x, x, x,...Я не знаю других в стандартной библиотеке.
так как вы попросили один лайнер:
__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