私はジェネレータをビルドする必要があり、私はこれを1行に短縮する方法を探していました。私は列挙しようとしましたが、うまくいきませんでした。このPythonジェネレータ表現を短縮する方法はありますか?
counter=0
for element in string:
if function(element):
counter+=1
yield counter
else:
yield counter
私はジェネレータをビルドする必要があり、私はこれを1行に短縮する方法を探していました。私は列挙しようとしましたが、うまくいきませんでした。このPythonジェネレータ表現を短縮する方法はありますか?
counter=0
for element in string:
if function(element):
counter+=1
yield counter
else:
yield counter
counter=0
for element in string:
counter+=bool(function(element))
yield counter
。 function()
はTrue
、False
、1
、および0
以外の戻り値を持つことができる場合
bool()
呼び出しが必要なだけです。
あなたが行うことができますPythonの3を、使用している場合:
from itertools import accumulate
yield from accumulate(1 if function(x) else 0 for x in string)
私はSimeon Visser's answerを使用すると思いますが。これは短いかもしれませんが、コードが何をしているかはすぐに分かりません。
@jamylak:最後に 'counter'変数はありません。 – Blender
'function'が0と1を明示的に返さないかぎり、これは機能しません。返り値が' None'や文字列の場合は、 'TypeError'がすべて返されます。 'True'と' False'を返しても、最初の値は '0'ではなく' False'になります。 – abarnert
"私は' accumulate'がブール値を返すと仮定しているのかどうかはわかりません。イテレータを返します。そして、それはあなたがそれを与える追加可能な型(あるいは、あなたがそれを与える型を加えた結果の上にあります。全く同じではありません。例えば、 'False + True == 1'、または古いPython、 '(1 << 31)+(1 << 31)=(1L << 32))。 – abarnert
あなたはそれを短縮することができます:(はい、int型にブール値を追加することが1
とFalse
た正確True
あるかのように動作する0
た)
counter=0
for element in string:
if function(element):
counter+=1
yield counter
私は実行カウントを保つ必要があるので、私はelse文も同様に生成する必要があります。 – garlfd
@garlfd:これは文字列内のすべての要素でも発生しますが、一部の要素に対してのみ更新されます。 –
まず、あなたがfunction
戻り値イテレータに文字列を変換することができます。
truths = (function(x) for x in string)
その後、あなたは0と1にそれらをマッピングすることができます
onesandzeroes = (1 if function(x) else 0 for x in string)
そしてaccumulateそれらを:
running = itertools.accumulate(1 if function(x) else 0 for x in string)
ドキュメントノートには、accumulate
が追加されましたPython 3.2。 2.xを使用している場合は、ドキュメントから「等価」レシピをコピーして貼り付けることができます。 (3.0-3.1を使用している場合は同じことができますが、その場合はアップグレードするだけです)
'counter = 0'が欠けていますか、これは何かの周りのクロージャーになっていますか? 'counter'は外側のコードにありますか? – abarnert
Pythonのどのバージョン? – Blender
いいえ、私はそれを最初から除外しましたが、私はそれを含めました。 – garlfd