2012-05-16 12 views
22

Estaba jugando con iterables y más específicamente con el operador yield en Python. Si bien la utilización de desarrollo basado en pruebas para comenzar a escribir una nueva iterable, me preguntaba qué es el código más corto que podría hacer esta prueba simple para un iterable que pasar:¿Cuál es la forma más simple de crear un iterable vacío usando rendimiento en Python?

def test(): 
    for x in my_iterable(): 
     pass 

La versión más corta que podía pensar era:

def my_iterable(): 
    for i in []: 
     yield i 

¿Es posible escribir una versión más simple, más corta o más hermosa (pitónica)?

+1

Tenga en cuenta que si su prueba iterable está vacía y no produce nada, como se muestra y en la mayoría o en todas las respuestas, su prueba no ejercerá ningún código en el ciclo 'for'. – martineau

Respuesta

18

Sí, hay:

return iter([]) 
+1

eso está bien, pero tengo: 'F999' advertencia – lang2

11

Puede usar las funciones lambda e iter para crear un iterable vacío en Python.

my_iterable = lambda: iter(()) 
1
def do_yield(): 
    return 
    yield None 

si el uso de yield es importante para usted, una de las otras respuestas de otro tipo.

+0

+1 para mantener' yield'. No es muy fácil de leer. :-) –

6

¿Qué tal

my_iterable = str 

este pasa la prueba.

Para hablar en serio, Iterable en el collections module dispone:

def __iter__(self): 
    while False: 
     yield None 

Esto puede ser considerado "más Pythonic" porque esto es lo que a su vez utiliza pitón.

Tenga en cuenta que técnicamente todas las respuestas hasta el momento proporcionan iteradores (__iter__ + next), no iterables (justo __iter__).

+0

Aceptado debido a la referencia a la biblioteca estándar de Python. –

0

Otra respuesta, ya que proporciono una solución completamente nueva con un enfoque diferente.

En una de las bibliotecas, tengo una EmptyIterator como

class EmptyIter(object): 
    __name__ = 'EmptyIter' 
    """Iterable which is False and empty""" 
    def __len__(self): return 0 
    def next(self): raise StopIteration # even that is redundant 
    def __getitem__(self, index): raise IndexError 

Es un enfoque alternativo que utiliza las siguientes propiedades:

  • iteración alternativa a través del protocolo de secuencia (ver here)
  • protocolo de "falsedad" alternativo como se describe here.
5

Otra solución, en Python 3, es el uso de la nueva yield from sintaxis:

def empty_gen(): 
    yield from() 

Cuál es legible, y tener empty_gen como generador.

+1

** Esto es todo. ** Mientras que respuestas como 'lambda: iter (())' satisfacen el instinto instintivo del hombre en cuanto a inteligencia, también son ilegibles y no producen un * generador real. * En particular, 'isinstance (iter (()), types.GeneratorType) == False'. Como muestra el éxito relativo de ['mypy'] (http://mypy-lang.org/), los tipos a veces * do * importan. Siempre 'rendimiento de', Python 3 personas. –

Cuestiones relacionadas