¿Existe una expresión generadora sencilla que pueda producir elementos infinitos?
Ésta es una cuestión puramente teórica. No hay necesidad de una respuesta "práctica" aquí :)
Por ejemplo, es fácil hacer un generador finito:
my_gen = (0 for i in xrange(42))
Sin embargo, para hacer uno infinito, necesito "contaminar" mi espacio de nombres con una función falsa:
def _my_gen():
while True:
yield 0
my_gen = _my_gen()
Hacer las cosas en un archivo separado y import
hacerlas más tarde no cuenta.
También sé que itertools.repeat
hace exactamente esto. Tengo curiosidad por saber si hay una solución de una sola línea sin eso.
python
iterator
generator
infinite-loop
hugomg
fuente
fuente
my_gen
y luego hazlomy_gen = my_gen()
.del _my_gen
si no quieres confundir a los dosRespuestas:
iter
= cero argumentos invocables + valor centinelaint()
siempre vuelve0
Por tanto,
iter(int, 1)
es un iterador infinito. Obviamente, hay una gran cantidad de variaciones sobre este tema en particular (especialmente una vez que lo agregaslambda
a la mezcla). Una variante de particular interés esiter(f, object())
que el uso de un objeto recién creado como valor centinela casi garantiza un iterador infinito independientemente del invocable utilizado como primer argumento.fuente
iter
con propiedadint
que muchas veces olvidamos.itertools.count
:count = lambda start=0, step=1: (start + i*step for i, _ in enumerate(iter(int, 1)))
iter
-función se llama con dos argumentos, se comporta un poco diferente de lo normal:iter(callable, sentinel) -> iterator
.callable
Se llama al argumento 1 para cada iteración del iterador, hasta que devuelve el valor desentinel
. Sin embargo, comoint()
siempre volverá0
, podemos llamarint()
para siempre y nunca llegar a 1. Esto, en efecto, producirá una lista infinita de0
'sitertools
proporciona tres generadores infinitos: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, ...No conozco a ningún otro en la biblioteca estándar.
Ya que pediste una sola línea:
fuente
∞
símbolo para quien se preguntó - omitir el argumento hace que se repita para siempreiter(int, 1)
encantamiento. Lástimaitertools
que no tenga unendlessly()
método cuyo único propósito sea hacer esto;itertools.count()
tampoco es tan legible.puede iterar sobre un invocable devolviendo una constante siempre diferente al centinela de iter ()
fuente
iter
(aquí con centinela extra) y la sintaxis delambda
(aquí sin ningún parámetro pasado, soloreturn 0
), el único lugar para odiar es ese enigmáticog1
.Su sistema operativo puede proporcionar algo que se puede utilizar como un generador infinito. Por ejemplo, en linux
obviamente esto no es tan eficiente como
fuente
\n
aparezcan s de vez en cuando ... ¡Devious! :)Ninguno que no use internamente otro iterador infinito definido como una clase / función / generador (no -expresión, una función con
yield
). Una expresión generadora siempre se basa en otro iterable y no hace más que filtrar y mapear sus elementos. No puede pasar de elementos finitos a infinitos con solomap
yfilter
, lo necesitawhile
(o unfor
que no termina, que es exactamente lo que no podemos tener usando solofor
iteradores finitos).Trivia: PEP 3142 es superficialmente similar, pero tras una inspección más cercana parece que todavía requiere la
for
cláusula (así que no(0 while True)
para usted), es decir, solo proporciona un atajo paraitertools.takewhile
.fuente
from itertools import repeat, count, cycle
probablemente cuenta como "fácilmente disponible" para la mayoría de las personas.iter
. Los iteradores infinitos están realmente disponibles como incorporados; vea mi respuesta :)Bastante feo y loco (sin embargo, muy divertido), pero puedes construir tu propio iterador a partir de una expresión usando algunos trucos (sin "contaminar" tu espacio de nombres como sea necesario):
fuente
Tal vez podrías usar decoradores como este, por ejemplo:
Uso (1):
Uso (2)
Creo que se podría mejorar aún más para deshacernos de esos feos
()
. Sin embargo, depende de la complejidad de la secuencia que desee poder crear. En términos generales, si su secuencia se puede expresar usando funciones, entonces toda la complejidad y el azúcar sintáctico de los generadores se puede ocultar dentro de un decorador o una función similar al decorador.fuente
def
y cierre? ;)(2^x)
, puedes tener(x)
. Si se mejora un poco, posiblemente, también de Fibonacci, etcseq
y sangrar el código directamente awrap