2012-03-26 2 views
7

可能性の重複:
The Python yield keyword explainedyieldがpython 2.7では何をするのですか?

さて、私はおそらくひどく質問を言葉で表現しましたが、これは私が持っている状況です。

私は理解しようとしているのPython 2.7でのコード行があります、このコード行で

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

padding_zerosが「0年代の可変数の文字列であり、number_stringが数値であります0から10000の間の任意の数値にすることができる文字列の形で入力します。

私は確かに.encode("ascii")がyieldの出力をasciiに変換すると確信しています。

私が完全に海で行っているのは、yield (padding_zeros + number_string)のことです。

私はジェネレータを開始することは知っていますが、オンラインで検索して構文を読み出すのに多くの時間を費やしましたが、実際にはジェネレータの内容は実際にはになりません。これは私の最初のpython(私の究極の目的は、このコードをC#に変換することです)を見ていることを助けることはありません。

だから、基本的に、誰かが私にこのコード行が何をしているのか説明してもらえますか?それはちょうど2つの文字列を一緒に追加するか、もう少し複雑なことをしますか?さらにコンテキストについて

が、これはコードのその行はに表示されることをブロックである: -

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") 

(何かの最大長さを示す数値max_lengthは、それが聞こえる正確に何です)

事前にすべての回答をお寄せいただきありがとうございます(たとえ、私にそのような騒がしい奴らではないと言っても)。

EDIT:ありがとうございます。彼らはすべての非常に有用だった最高の答えとしてick 1。コメントのお寄せいただきありがとうございます - そのうちのいくつかが指摘しているように、What does the "yield" keyword do in Python?は、私が特定の状況への答えを見つけられなかったとしても、歩留まり、発電機、反復の非常に良い一般的なガイドです:)

+0

はこのPythonの2またはPythonの3か? –

+0

こんにちはジョージ、あなたの質問は私が感じる非常によくここに答えている:http://stackoverflow.com/questions/231767/the-python-yield-keyword-explained – MattH

+0

この回答を見る:http://stackoverflow.com/questions/231767/the-python-yield-keyword-described/231855#231855 –

答えて

6

[OK]を、あなたは発電機について知っているので、yield部分は何の説明を必要としません。ファイン。

その行は実際に何をしていますか?それほど多くない:

padding_zerosnumber_stringを連結し、結果をASCIIにエンコードします。 Python 2.7では、文字列がASCIIで始まるので(これは定義上ASCII文字のみで構成されるため)、no-opになります。

Python 3では、それは異なるでしょう。ここで.encode()は文字列をbytesオブジェクトに変換していました。しかし、Python 2では、それは意味をなさない。

+0

ありがとうございます - このコードはもともとはPython 3で書かれていて、なぜPython 2には何も表示されない理由を説明しているかもしれません。あなたの答えをありがとう、非常に無知のために申し訳ありません。 – GeorgePotter

1

ケースyieldを使用して遅延評価を実行します。次のコードはほぼ同じです:

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() 

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()) 

あなたはちょうどあなたのコード変換で二番目に従うことができます。

+1

2番目のバージョンはリストを返しますが、ジェネレータは各要素を1つずつ出力します。 – Marcin

+0

ありがとうございました:) – GeorgePotter

+0

@Marcin sure。しかし、私はOPが心配しているとは思わない:) –

3

yieldは、ジェネレータでのリターンのようなものです。

yieldが実行された時点で、ジェネレータ関数の実行が停止し、値が返されます。違いは、ジェネレータが再び呼び出されると、yield文で実行が再開され、別のyieldがヒットするか、(未処理の)例外が発生するか、returnがヒットするまで続きます。 returnまたは例外はジェネレータを終了します。

ジェネレータのポイントは、それをx = next(generator)またはx = generator.next()と呼び出すことができ、ジェネレータ内の歩留まりから値を受け取るたびに発生する点です。ジェネレータも反復可能であるため、ループのソースとして使用することができます:for x in generator: print x

C#の場合と同様に、.演算子は、演算子の左に表示されているオブジェクトの右側に指定されたメソッドを呼び出します。したがって、(padding_zeros + number_string).encode("ascii")(padding_zeros + number_string)の結果としてencodeと呼び出します。 encodeの意味について

、こちらをご覧ください:言語リファレンス(あなたのpython 2を使用していると仮定)についてはhttp://docs.python.org/library/stdtypes.html#str.encode

http://docs.python.org/reference/index.html

+1

ありがとうございました:) – GeorgePotter

+0

@GeorgePotter問題ありません。自由に回答を受け入れることができます。あなたが有益であれば投票してください。 – Marcin

0

ジェネレータは、イテレータインタフェースまたはPythonで__iter__を実装するステートマシンです。 next()を呼び出すまで "yield"の後で待機します。

これを試してみてください。

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

ジェネレータはStatemachine -1:http://en.wikipedia.org/wiki/Finite-state_machineではありません。さらに、主要ジェネレータインターフェイスは「次へ」です。 – Marcin

+0

私はそれが(非常に単純なものだと)思う:next()へのすべての呼び出しは、その状態を前進または停止することができるように変更する。 (私は2番目の '__iter__'を 'next()'に編集しました) –

+0

これはステートマシンの定義ではありません。 – Marcin

関連する問題