a or b or c or ... 続き
(えー、ネタが思いつかないのでコメントネタで)
以前最初の真値を返すというので
next(ifilter(None, iter(x)), None)
てのをやりましたが、これって厳密には「a or b or c or ...」と仕様が違うんじゃね、というコメントいただきました
...まあ、そうなんですよね。すべて偽値だった場合は
- a or b or c or ... → 最後の値が返される
- next(ifilter(None, ...), None) → Noneが返される
と結果が違うわけです。
じゃあ、厳密にやってみようということで。
ひとまず真偽は関係ないことにして、イテレータの「最後の要素」を返したいって場合
def last(it): x = None for x in it: pass return x it = iter([4, 1, 6, 3]) print last(it)
3
だまってループを回せばいいですよね(イテレータは消費しちゃいますけど)。
ただこれはPythonでループを回しているので、ちょっとパフォーマンスが気になります。
ここで困ったときのStack Overflow頼み(ぉ
http://stackoverflow.com/questions/2138873/cleanest-way-to-get-last-item-from-python-iterator
from collections import deque def last(it): return deque(it, maxlen=1).pop()
1つしか値が入らないキューを作ってイテレータを消費させてしまうという手で、これがたぶん最速じゃないかということのようです。
ということで、「最初に出てくる真値を返すが、すべて偽だった場合は最後の値を返す」というのは
from collections import deque from itertools import ifilter, tee def anytrue(it): it0, it1 = tee(it) try: return ifilter(None, it0).next() except StopIteration: return deque(it1, maxlen=1).pop()
全然エレガントじゃなくなりました... orz