2012-03-26 13 views
7

Mögliche Duplizieren:
The Python yield keyword explainedWas macht die Ausbeute in Python 2.7?

Okay, habe ich formuliert wahrscheinlich die Frage schlecht, aber das ist die Situation, die ich habe.

Ich habe diese Zeile Code in Python 2.7, die ich zu verstehen, ich versuche:

yield (padding_zeros + number_string).encode("ascii") 

In dieser Codezeile ist padding_zeros eine Zeichenfolge aus einer variablen Anzahl von ‚0-en und number_string eine Zahl in Form einer Zeichenfolge, die eine beliebige Zahl zwischen 0 bis, sagen wir 10000 sein kann.

Ich bin ziemlich sicher, dass die .encode("ascii") konvertiert nur die Ausgabe von Ertrag zu Ascii.

Was ich bin völlig auf See ist, was die yield (padding_zeros + number_string) tut.

Ich weiß, dass es einen Generator initiiert, aber ich habe viel Zeit damit verbracht, online zu suchen und auf der Syntax zu lesen, aber ich kann immer noch nicht herausfinden, was der Generator tut. Es ist nicht hilfreich, dass ich Python das erste Mal betrachte (mein ultimatives Ziel ist es, diesen Code in C# umzuwandeln).

Also, im Grunde könnte bitte jemand mir erklären, was diese Codezeile tut? Fügt es einfach die beiden Strings zusammen oder macht es etwas komplizierter?

Für weiteren Kontext, das ist der Block, dass die Codezeile in erscheint:

for current_length in range(4, max_length + 1): 
    for i in range(0, pow(10, current_length)): 
     number_string = str(i) 
     padding_zeros = "0" * (current_length - len(number_string)) 
     yield (padding_zeros + number_string).encode("ascii") 

(genau max_length zu sein, was es klingt - eine Zahl, die die maximale Länge von etwas anzeigt)

Vielen Dank im Voraus für alle Antworten (auch wenn sie mir sagen, dass ich nicht so ein frommes Noob sein soll) :)

EDIT: Vielen Dank für die Antworten - obwohl ich nur p ick eins als das beste answe sie waren alle sehr hilfsbereit. Und danke für die Kommentare auch - wie einige von ihnen darauf hingewiesen, What does the "yield" keyword do in Python? ist eine sehr gute allgemeine Anleitung zum Ertrag, Generatoren und Iterationen, auch wenn ich keine Antwort auf meine spezifische Situation gefunden habe :)

+0

Ist das Python 2 oder Python 3? –

+0

Hallo George, Ihre Frage wurde hier ziemlich gut beantwortet Ich fühle: http://StackOverflow.com/Questions/231767/the-Python-Yield-Keyword-explained – MattH

+0

Siehe diese Antwort: http://StackOverflow.com/Questions/231767/the-python-yield-keyword-declared/231855 # 231855 –

Antwort

6

OK, wissen Sie über Generatoren, so dass der yield Teil bedarf keiner Erklärung . Fein.

Was macht diese Linie eigentlich? Nicht sehr viel:

Es verkettet padding_zeros und number_string und codiert dann das Ergebnis in ASCII. Was in Python 2.7 ist ein No-Op, weil die Zeichenfolge ASCII ist (es besteht per Definition nur aus ASCII-Ziffern).

In Python 3 wäre es anders; Hier hätte die .encode() die Zeichenfolge in ein bytes Objekt umgewandelt. Aber in Python 2 macht es keinen Sinn.

+0

Danke - es könnte sein, dass dieser Code ursprünglich in Python 3 geschrieben wurde, was erklären würde, warum er in Python 2 als kein Op erscheint. Kann aber nicht zu 100% sicher sein. Danke für deine Antwort und sorry dafür, dass du so ahnungslos bist. – GeorgePotter

1

In diesem Fall yield wird verwendet, um faule Auswertung durchzuführen. Die nächsten Codes sind in etwa gleichwertig:

def f(...): 
    for current_length in range(4, max_length + 1): 
     for i in range(0, pow(10, current_length)): 
      number_string = str(i) 
      padding_zeros = "0" * (current_length - len(number_string)) 
      yield (padding_zeros + number_string).encode("ascii") 

result = list(f()) 

gegen

def f(...): 
    result = list() 
    for current_length in range(4, max_length + 1): 
     for i in range(0, pow(10, current_length)): 
      number_string = str(i) 
      padding_zeros = "0" * (current_length - len(number_string)) 
      result.append((padding_zeros + number_string).encode("ascii")) 
    return result 

result = f() 

Sie können nur die zweite in Sie Code Übersetzung folgen.

+1

Außer, dass die zweite Version eine Liste zurückgibt, während der Generator jedes Element eins nach dem anderen ergibt. – Marcin

+0

Vielen Dank :) – GeorgePotter

+0

@Marcin sicher. Aber ich denke nicht, dass OP sich darum kümmert :) –

3

yield ist wie Rückkehr in einem Generator.

An dem Punkt, an dem die yield ausgeführt wird, stoppt die Ausführung der Generatorfunktion, und der Wert wird zurückgegeben.Der Unterschied besteht darin, dass bei erneutem Aufruf des Generators die Ausführung bei der yield-Anweisung neu startet und fortgesetzt wird, bis eine andere Ausbeute erreicht wird oder eine (nicht behandelte) Ausnahme ausgelöst wird oder return erreicht wird. Die return oder Ausnahme beendet den Generator.

Der Punkt eines Generators ist, dass man ihn als x = next(generator) oder x = generator.next() aufrufen kann, und jedes Mal erhält man den Wert aus der Ausbeute im Generator. Generatoren sind auch iterierbar, so dass sie als Quelle für eine Schleife verwendet werden können: for x in generator: print x.

Wie in C# ruft der Operator . die Methode auf, die rechts auf dem Objekt steht, das auf der linken Seite des Operators erscheint. Dementsprechend ruft (padding_zeros + number_string).encode("ascii")encode auf das Ergebnis (padding_zeros + number_string).

Zur Bedeutung von encode finden Sie hier: http://docs.python.org/library/stdtypes.html#str.encode

Für die Sprachreferenz (vorausgesetzt, Sie Python verwenden 2): http://docs.python.org/reference/index.html

+1

Vielen Dank :) – GeorgePotter

+0

@GeorgePotter Kein Problem. Fühlen Sie sich frei, eine Antwort zu akzeptieren, und stimmen Sie alle anderen ab, die Sie hilfreich finden (sobald Sie in der Lage sind, abzustimmen). – Marcin

0

Ein Generator ist eine Statemachine, die die Iterator-Schnittstelle oder __iter__ in Python implementiert. es wird nach "Ausbeute" warten, bis Sie nächsten() darauf aufrufen.

versuchen Sie dies:

def my_gen(): 
    for current_length in range(4, max_length + 1): 
     for i in range(0, pow(10, current_length)): 
      number_string = str(i) 
      padding_zeros = "0" * (current_length - len(number_string)) 
      print "generate %s" % i 
      yield (padding_zeros + number_string).encode("ascii") 

for i in my_gen(): 
    print "iterate %s" % i 
+0

Ein Generator ist kein Statemachine -1: http://en.wikipedia.org/wiki/Finite-State_machine. Zusätzlich ist die primäre Generatorschnittstelle "next". – Marcin

+0

Ich denke, es ist (eine ziemlich einfache): jeder Aufruf von next() ändert seinen Zustand, der es ermöglicht, vorwärts zu gehen oder zu stoppen. (Ich editierte die zweite '__iter__' zu 'next()') –

+0

Das ist nicht die Definition einer Staatsmaschine. – Marcin