Pythonの:句があれば空まで来ていないと非空のリストに対する反復。どうして?
-
22-08-2019 - |
質問
どのようにフィルタリングしていない集計(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
ないですので...