转换为集合后,以相同的顺序打印列表值

时间:2013-10-10 21:02:43

标签: python

例如:

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

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

它为我提供了一个值列表,这样每个值只出现一次,但我希望它也以与原始列表相同的顺序打印它们。

2 个答案:

答案 0 :(得分:6)

set没有订单,因此在将列表转换为集合后,迭代元素时的结果顺序是实现细节。

您可以使用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]

答案 1 :(得分: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]

<强>基准

Poke's answer

>>> 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秒。