Pythonの:句があれば空まで来ていないと非空のリストに対する反復。どうして?

StackOverflow https://stackoverflow.com/questions/703520

質問

どのようにフィルタリングしていない集計(sum()など)なしで空でないシーケンスの反復子は、何も得られないことができますか?

簡単な例を考えてみます:

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

このは[('a', 97), ('b', 98), ('c', 99)]を得ています。

次に、ちょうどord(el)を使用して、いくつかの発電機のうちの最初の値をとる発現のため(...).next()をスワップアウト - 不自然な例を許す

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)

このは[]を生み出します。うん、空のリスト。いいえ('a',stuff)タプルません。ナッシングます。

しかし、私たちは、フィルタリングまたは集約や縮小していません。フィルタリングまたは凝集することなくnオブジェクトの上にジェネレータ式は右、nオブジェクトを生成しなければなりませんか?何が起こっているのですか?

役に立ちましたか?

解決

odd_integers_up_to_length(el).next()がキャッチされていませんが、その中にジェネレータ式のために捕捉され、これまでに何をもたらすことなく、それを止める呼び出すとStopIterationを発生させます。

の値が 'A' であるとき、最初の反復を見ます:

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

他のヒント

何が起こるかというとnext()コールが外側ジェネレータ式にスタックをバブルアップし、のことの反復を停止しStopIteration例外を発生させていることである。

StopIterationは、それが行われますことを知らせるために、イテレータのための通常の方法です。一般next()コールがイテレータを消費構文内で発生するため、一般的に、我々は、例えば、それを見ることはありませんfor x in iteratorまたはsum(iterator)。私たちが直接next()を呼び出すときしかし、私たちはStopIterationをキャッチする責任ものです。そうしないと、ここでは、外側の反復で予期しない動作につながる、抽象化のリークをバネます。

レッスン、私は考えます:next()への直接呼び出しには注意が

strが予約済みのキーワードである、あなたは違った自分の変数に名前を付ける必要があります。

私は次の

について助言することもありました
>>> seq=['a','b','c']
>>> list((el,4) for el in seq)
[('a',4), ('b',4), ('c',4)]

それはここにあなたにトラブルを与えてlistないですので...

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top