Frage

Wie kann ein Iterator über eine nicht leere Sequenz, ohne Filterung und keine Aggregation (sum(), etc.), ergibt nichts?

Betrachten wir ein einfaches Beispiel:

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

Dies ergibt [('a', 97), ('b', 98), ('c', 99)] wie erwartet.

Nun tauschen nur die ord(el) für einen Ausdruck aus, der aus irgendeinem Generator (...).next() mit dem ersten Wert annimmt - vergeben das erfundene Beispiel:

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)

Dies ergibt []. Ja, leere Liste. Keine ('a',stuff) Tupel. Nichts.

Aber wir sind nicht Filterung oder Aggregation oder verringert wird. Ein Generator Ausdruck über n Objekte ohne Filterung oder Aggregation müssen n Objekte ergeben, nicht wahr? Was ist los?

War es hilfreich?

Lösung

odd_integers_up_to_length(el).next() erhöhen wird StopIteration, die nicht dort gefangen wird, ist aber für den Generator Ausdruck in ihr gefangen, es zu stoppen, ohne jemals etwas nachgebend.

Blick auf der ersten Iteration, wenn der Wert 'a':

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

Andere Tipps

Was passiert, ist, dass der next() Aufruf eine StopIteration Ausnahme auslöst, die den Stapel an den äußeren Generator Ausdruck Blasen nach oben und stoppen , die Iteration.

Ein StopIteration ist der normale Weg für ein Iterator zu signalisieren, dass es gemacht wird. Im Allgemeinen wir sehen es nicht, weil in der Regel der next() Anruf innerhalb eines Konstrukts auftritt, die den Iterator verbraucht, z.B. for x in iterator oder sum(iterator). Aber wenn wir next() direkt anrufen, sind wir es, die verantwortlich für die StopIteration zu kontrollieren. Nicht dabei ein Leck in dem Abstraktion Federn, die hier zu unerwartetem Verhalten führt in der äußeren Iteration.

Die Lektion, nehme ich an: über direkte Aufrufe next() vorsichtig sein

.

str ein reserviertes Schlüsselwort ist, sollten Sie Ihre Variablennamen anders

Ich war auch über die nächste

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

So ist es nicht list Sie Probleme geben hier ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top