シーケンスの順番を維持したままuniq化する

リストの順番を維持したままユニーク化(=後に出てくる同じ要素はカットする)を行う方法です。

>>> # (Python 2.6)

>>> L = [5,2,6,5,2,3,6,1,4,2]

>>> list(set(L))
[1, 2, 3, 4, 5, 6]

>>> [x for x in L if x not in locals()['_[1]'] ]
[5, 2, 6, 3, 1, 4]

setを使った方法は順番が変わっていますが、2番目の方法は順番が維持されています。
これは「リスト内包表記の作成途中のリストを読み出す」裏技を使っています。「_[1]」という変数に作成途中のリストが入っているのですが、これは「変数_のインデックス1」という意味ではなく「_[1]」というひとつながりの変数名です。locals()を使わないとアクセスできません。
リスト内包表記をネストさせた場合は「_[2]」「_[3]」とかも作られるようです。
この技はいろいろなところで紹介されていて、さらに応用して「リスト内包表記だけで素数の列を作る」なんて大技も披露されていました。

しかしこの裏技はPython 2.7でなくなりました。locals()['_[1]'] はKeyErrorとなります。
ということで、uniq化の別の方法として「どう書く?org」に載っている方法を挙げます。
http://ja.doukaku.org/16/lang/python/

>>> sorted(set(L), key=L.index)
[5, 2, 6, 3, 1, 4]

これが一番綺麗な方法だと思います。要素数が極端に多いとindexやsortedにかかる時間が気になるかもしれないですが。

>>> reduce(lambda a,b: a+[b] if b not in a else a, L, [])
[5, 2, 6, 3, 1, 4]

reduceを使う方法。何となくこれが一番速そうな気もしますが... 後で測定してみようかな。

def uniq(it):
    s = set()
    for x in it:
        if x not in s:
            yield x
            s.add(x)

print list(uniq(L))

forループで速度が気になりますが、要素が少ないなら実直に処理するのもありかもしれません。