3

例えば:

>>> a
[2, -4, -2, 4, -3, -1, 3, 4, 2, 2]

>>> unique(a)
[2, 3, 4, -2, -4, -3, -1]

各値が 1 回だけ表示されるような値のリストが表示されますが、元のリストと同じ順序で出力したいと考えています。

4

2 に答える 2

6

Asetには順序がないため、リストをセットに変換した後、要素を反復するときの結果の順序は実装の詳細です。

を使用しOrderedDictて、注文で一定の​​動作を取得できます。

>>> from collections import OrderedDict
>>> a = [2, -4, -2, 4, -3, -1, 3, 4, 2, 2]
>>> x = OrderedDict.fromkeys(a)
>>> list(x)
[2, -4, -2, 4, -3, -1, 3]
于 2013-10-10T21:07:32.220 に答える
0

これは、基本的に元のリストの要素を繰り返し処理し、追加するリストにまだ含まれているかどうかを確認する、より高速な(コンパクトsetではありませんが)アプローチです。私のアプローチをさらにスピードアップする可能性のあるいくつかの微妙な変更があるかもしれません:

def _order(orig):
    ordset = set()
    for x in orig:
        if x in ordset:
            continue
        ordset.add(x)
        yield x
def unique(orig):
    return list(_order(orig))

出力:

>>> unique(a)
[2, -4, -2, 4, -3, -1, 3]

ベンチマーク:

ポケの答え

>>> import timeit
>>> setup = '''
a = [2, -4, -2, 4, -3, -1, 3, 4, 2, 2]
from collections import OrderedDict
def unique():
    x = OrderedDict.fromkeys(a)
    return list(x)
'''
>>> print (min(timeit.Timer('unique()', setup=setup).repeat(100, 1000)))
0.031305141204512665

上記の答え:

>>> import timeit
>>> setup = '''
a = [2, -4, -2, 4, -3, -1, 3, 4, 2, 2]
def _order(orig):
    ordset = set()
    for x in orig:
        if x in ordset:
            continue
        ordset.add(x)
        yield x
def unique(orig):
    return list(_order(orig))
'''
>>> print (min(timeit.Timer('unique(a)', setup=setup).repeat(100, 1000)))
0.0031761333803501657

このアプローチは、ほぼ 10 倍高速です。このような小さなリストの場合、違いはごくわずかであり、Poke の回答は素晴らしいものです。ただし、大規模なリスト (たとえば、10000 倍長いリスト) に対してこれを行った場合、5 秒と比較して 75 秒の差があります。

于 2015-04-15T15:24:26.130 に答える