Python の最も同等な方法:while ((x = next()) != END)
質問
この C 構造に最適な Python イディオムは何ですか?
while ((x = next()) != END) {
....
}
next() を再コードする能力がありません。
アップデート:そして、からの答えは次のようです:
for x in iter(next, END):
....
解決
短い答え:Python の while ループでインライン変数の代入を行う方法はありません。つまり、私は できない 言う:
while x=next():
// do something here!
それは不可能なので、これを行うための「慣用的に正しい」方法がいくつかあります。
while 1:
x = next()
if x != END:
// Blah
else:
break
明らかに、これはちょっと醜いです。上記の「反復子」アプローチのいずれかを使用することもできますが、これも理想的ではない可能性があります。最後に、私が実際にグーグルで見つけた「ピタポケット」アプローチを使用することもできます。
class Pita( object ):
__slots__ = ('pocket',)
marker = object()
def __init__(self, v=marker):
if v is not self.marker:
self.pocket = v
def __call__(self, v=marker):
if v is not self.marker:
self.pocket = v
return self.pocket
これで、次のことができるようになります。
p = Pita()
while p( next() ) != END:
// do stuff with p.pocket!
ご質問ありがとうございます。について学ぶ __call__
イディオム本当にかっこよかったです!:)
編集:クレジットされるべきところはクレジットしたいと思います。「ピタポケット」という慣用句が見つかりました ここ
他のヒント
@マーク・ハリソンの答え:
for x in iter(next_, END):
....
ここからの抜粋です Python のドキュメント:
iter(o[, sentinel])
イテレータオブジェクトを返します。 ...(をちょきちょきと切る)... 第 2 引数の場合、
sentinel
, が与えられると、o
呼ばれるオブジェクトである必要があります。この場合に作成されたイテレーターは呼び出しますo
それぞれの呼び出しに引数はありませんnext()
方法;返される値が等しい場合sentinel
,StopIteration
それ以外の場合は、値が返されます。
それはあなたが何をしたいかによって少し異なります。可能な限りあなたの例に一致させるために、次にジェネレーターを作成し、それを反復処理します。
def next():
for num in range(10):
yield num
for x in next():
print x
あまり慣用的ではないかもしれませんが、私はこうしたいと思います
x = next()
while x != END:
do_something_with_x
x = next()
...でもそれはそういうのが読みやすいからです
ここで何をしようとしているのですか?リストを反復処理している場合は、次を使用できます for e in L
ここで、e は要素、L はリストです。リストをフィルタリングしている場合は、リスト内包表記を使用できます (つまり、 [ e for e in L if e % 2 == 0 ]
リスト内のすべての偶数を取得します)。
達成しようとしていることについてさらに詳しい情報を提供してもらえますか?なぜそう言えないのか私にはわかりません
for x in everything():
...
一度に 1 つだけを返す next 関数を作成する代わりに、everything 関数がすべてを返すようにします。ジェネレーターはこれを非常に効率的に実行することもできます。
これを複数回行う必要がある場合、Python の方法ではイテレータを使用します。
for x in iternext():
do_something_with_x
どこ iternext
次のようなものを使用して定義されます暗黙的よりも明示的な方が優れています。):
def iternext():
x = next()
while x != END:
yield x
x = next()