web-dev-qa-db-fra.com

rupture de rendement dans Python

selon la réponse à cette question , la rupture de rendement en C # équivaut à retourner en python. dans le cas normal, 'return' arrête en effet un générateur. Mais si votre fonction ne fait rien d'autre que retourner, vous obtiendrez un Aucun, pas un itérateur vide, qui est retourné par yield break en C #

def generate_nothing():
    return

for i in generate_nothing():
    print i

vous obtiendrez une TypeError: l'objet 'NoneType' n'est pas itérable. mais si j'ajoute un rendement jamais exécuté avant le retour, cette fonction retourne ce que j'attends.

def generate_nothing():
    if False: yield None
    return

si fonctionne mais semble câblé. Qui a une meilleure idée?

merci,

49
Sonic Lee
def generate_nothing():
    return
    yield
45
ninjagecko

Une bonne façon de gérer cela consiste à augmenter StopIteration qui est généré lorsque votre itérateur n'a plus rien à céder et que next() est appelée. Cela sortira également gracieusement d'une boucle for sans rien à l'intérieur de la boucle exécutée.

Par exemple, étant donné un Tuple (0, 1, 2, 3) Je veux obtenir des paires qui se chevauchent ((0, 1), (1, 2), (2, 3)). Je pourrais le faire comme ça:

def pairs(numbers):
    if len(numbers) < 2:
        raise StopIteration

    for i, number in enumerate(numbers[1:]):
        yield numbers[i], number

Maintenant, pairs gère en toute sécurité les listes avec 1 nombre ou moins.

45
Sam Simmons
def generate_nothing():
    return iter([])
6
phihag

La partie amusante est que les deux fonctions ont le même bytecode. Il y a probablement un indicateur qui prend la valeur generator lorsque le compilateur de bytecode trouve le mot clé 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
1
JBernardo