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