Actualmente estoy haciendo esto:
try:
something = iterator.next()
# ...
except StopIteration:
# ...
Pero me gustaría una expresión que pueda colocar dentro de una if
declaración simple . ¿Hay algo integrado que haga que este código parezca menos torpe?
any()
devuelve False
si un iterable está vacío, pero potencialmente iterará sobre todos los elementos si no lo está. Solo lo necesito para comprobar el primer elemento.
Alguien pregunta qué estoy tratando de hacer. He escrito una función que ejecuta una consulta SQL y produce sus resultados. A veces, cuando llamo a esta función, solo quiero saber si la consulta devolvió algo y tomar una decisión basada en eso.
Respuestas:
any
no irá más allá del primer elemento si es True. En caso de que el iterador produzca algo falso, puede escribirany(True for _ in iterator)
.fuente
any((x > 100 for x in xrange(10000000)))
y luego ejecuteany((x > 10000000 for x in xrange(100000000)))
; el segundo debería llevar mucho más tiempo.sum(1 for _ in itertools.islice(iterator, max_len)) >= max_len
all(False for _ in iterator)
verificará si el iterador está vacío. (todo devuelve True si el iterador está vacío; de lo contrario, se detiene cuando ve el primer elemento False)En Python 2.6+, si el nombre
sentinel
está vinculado a un valor que el iterador no puede producir,Si no tiene idea de lo que posiblemente podría producir el iterador, cree su propio centinela (por ejemplo, en la parte superior de su módulo) con
De lo contrario, podría utilizar, en el rol de centinela, cualquier valor que "conozca" (según las consideraciones de la aplicación) que el iterador no pueda obtener.
fuente
if not next(iterator, None):
fue suficiente ya que estaba seguro de que Ninguno no sería parte de los elementos. ¡Gracias por señalarme en la dirección correcta!not
devolverá True para cualquier objeto falso, como listas vacías, False y cero.is not None
es más seguro y, en mi opinión, más claro.Esto no es realmente más limpio, pero muestra una forma de empaquetarlo en una función sin pérdidas:
Esto no es realmente pitónico y, para casos particulares, probablemente haya soluciones mejores (pero menos generales), como la siguiente predeterminada.
Esto no es general porque None puede ser un elemento válido en muchos iterables.
fuente
next()
.tee
in itertools tendrán que mantener cada elemento del iterador original en caso de queany_check
alguna vez necesite avanzar. Esto es peor que simplemente convertir el iterador original en una lista.puedes usar:
pero es un poco inexplicable para el lector de código
fuente
La mejor forma de hacerlo es con un
peekable
frommore_itertools
.Solo tenga cuidado si mantuvo referencias al antiguo iterador, ese iterador avanzará. Tienes que usar el nuevo iterador visible a partir de ese momento. Realmente, sin embargo, peekable espera ser el único fragmento de código que modifique ese antiguo iterador, por lo que no debería mantener referencias al antiguo iterador de todos modos.
fuente
Qué pasa:
fuente
class NotSet: pass
, luego verificaif next(i, NotSet) is NotSet: print("Iterator is empty")
__length_hint__
estima la longitud delist(it)
su método privado, aunque:fuente
Este es un contenedor de iterador exagerado que generalmente permite verificar si hay un elemento siguiente (a través de la conversión a booleano). Por supuesto bastante ineficiente.
Salida:
fuente
Un poco tarde, pero ... podría convertir el iterador en una lista y luego trabajar con esa lista:
fuente