同等の値を生成する反復子が与えられた場合、すべての結果が等しいかどうかをチェックする怠惰な方法は何でしょうか。つまり、ジェネレーター全体を消費することなく、できるだけ早く失敗します。だからlen(set(g))==1
うまくいきません。
ライブラリ関数の簡単な表現・組み合わせを探しています。いいえdef
。
どうですか:
first = next(gen)
if all(x==first for x in gen):
print "They're all the same!"
(Rob Woutersはこのアルゴリズムをコメントで説明しました、私はそれをPythonに入れました)
FJが発見したように、これは空のイテレータでは失敗します。これは、イテレータだけでなく、すでにイテレータを持っていることを前提としています。彼の答えは両方の点に対応しています。
@unutbu によって与えられた式
all(y == first for first in gen for y in gen)
テスト/デモ:
>>> def test(*args):
... for a in args:
... print a,
... yield a
...
>>> g = test(1,1,1,1,1,1,1)
>>> print all(a == x for a in g for x in g)
1 1 1 1 1 1 1 True
>>> g = test(1,1,1,2,1,1,1)
>>> print all(a == x for a in g for x in g)
1 1 1 2 False
必要に応じて、早期に失敗しました。
def all_equal(iterable):
itr = iter(iterable)
try:
first = next(itr)
except StopIteration:
return True
else:
return all(item == first for item in itr)
True
空の反復可能オブジェクトの戻り値from itertools import *
if all(a == b for a, b in izip(gen, islice(gen, 1, None))):
print "They're all the same!"
ただし、イテレータでは機能しません。
gen1, gen2 = tee(gen)
next(gen1, None)
if all(a == b for a, b in izip(gen1, gen2)):
print "They're all the same!"
または「単一の式」として:
if (lambda g, h: all(a == b for a, b in izip(g, islice(h, 1, None))))(*tee(gen)):
print "They're all the same!"