working with what used print generators funcion for explicacion are python generator yield

with - ruptura de rendimiento en Python



what are python generators used for (4)

de acuerdo a la respuesta a esta question , la ruptura de rendimiento en C # es equivalente a la devolución en python. en el caso normal, ''retorno'' de hecho detiene un generador. Pero si su función no hace más que regresar, obtendrá un iterador Ninguno, no vacío, que se devuelve mediante el límite de rendimiento en C #

def generate_nothing(): return for i in generate_nothing(): print i

obtendrá un TypeError: el objeto ''NoneType'' no es iterable. pero si agrego un rendimiento nunca ejecutado antes del retorno, esta función devuelve lo que espero.

def generate_nothing(): if False: yield None return

si funciona pero parece cableado ¿Quién tiene una mejor idea?

Gracias,


La parte divertida es que ambas funciones tienen el mismo bytecode. Probablemente hay un indicador que se establece en el generator cuando el compilador de bytecode encuentra la palabra clave yield .

>>> def f(): ... return >>> def g(): ... if False: yield #in Python2 you can use 0 instead of False to achieve the same result >>> from dis import dis >>> dis(f) 2 0 LOAD_CONST 0 (None) 3 RETURN_VALUE >>> dis(g) 2 0 LOAD_CONST 0 (None) 3 RETURN_VALUE


Una buena forma de manejar esto es levantar StopIteration que es lo que se StopIteration cuando su iterador no tiene nada más que ceder y se StopIteration a next() . Esto también saldrá con gracia de un bucle for sin nada dentro del bucle ejecutado.

Por ejemplo, dada una tupla (0, 1, 2, 3) , quiero obtener pares superpuestos ((0, 1), (1, 2), (2, 3)) . Podría hacerlo así:

def pairs(numbers): if len(numbers) < 2: raise StopIteration for i, number in enumerate(numbers[1:]): yield numbers[i], number

Ahora los pairs manejan con seguridad las listas con 1 número o menos.


def generate_nothing(): return yield


def generate_nothing(): return iter([])