Question

Comment un itérateur sur une séquence non vide, sans filtrage ni agrégation (sum(), etc.), rien? Rendement

Prenons un exemple simple:

sequence = ['a', 'b', 'c']
list((el, ord(el)) for el in sequence)

On obtient ainsi [('a', 97), ('b', 98), ('c', 99)] comme prévu.

Maintenant, juste échanger l'ord(el) pour une expression qui prend la première valeur de certains générateur utilisant (...).next() - pardonnez l'exemple artificiel:

def odd_integers_up_to_length(str):
    return (x for x in xrange(len(str)) if x%2==1)

list((el, odd_integers_up_to_length(el).next()) for el in sequence)

Cela donne []. Ouais, liste vide. Pas ('a',stuff) tuples. Rien.

Mais nous ne sommes pas le filtrage ou l'agrégation ou la réduction. Une expression de la génératrice sur les objets n sans filtrage ou d'agrégation doit céder les objets n, à droite? Que se passe-t-il?

Était-ce utile?

La solution

odd_integers_up_to_length(el).next() soulèvera StopIteration, qui n'y est pas pris, mais il est pris pour l'expression du générateur en son sein, arrêter sans jamais rien céder.

regardez la première itération, lorsque la valeur est 'a':

>>> odd_integers_up_to_length('a').next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

Autres conseils

Ce qui se passe est que l'appel de next() génère une exception StopIteration, qui bouillonne la pile à l'expression de la génératrice externe et arrête que itération.

A StopIteration est la voie normale pour un itérateur pour signaler qu'il est fait. En général, nous ne voyons pas, parce que généralement l'appel next() se produit dans une construction qui consomme le iterator, par exemple for x in iterator ou sum(iterator). Mais quand nous appelons next() directement, nous sommes responsables pour prendre le StopIteration. Ne pas faire ressorts si une fuite dans l'abstraction, ce qui conduit ici à un comportement inattendu dans l'itération externe.

La leçon, je suppose: attention sur les appels directs à next()

.

str est un mot-clé réservé, vous devez nommer différemment votre variable

Je suis également conseiller sur la prochaine

>>> seq=['a','b','c']
>>> list((el,4) for el in seq)
[('a',4), ('b',4), ('c',4)]

Il est list ne vous donne pas mal à ici ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top