关于unique:在Python列表中进行排序加uniq的最简洁方法是什么?

What is the cleanest way to do a sort plus uniq on a Python list?

考虑含['foo', 'foo', 'bar']my_listPython列表。

什么是最uniquifyPython路和排序的列表?(cat my_list | sort | uniq智囊团)

这是我目前在做它的工作和我肯定有更好的方法做的。

1
2
3
4
5
6
7
8
9
my_list = []
...
my_list.append("foo")
my_list.append("foo")
my_list.append("bar")
...
my_list = set(my_list)
my_list = list(my_list)
my_list.sort()


1
my_list = sorted(set(my_list))


1
2
3
4
5
6
7
# Python ≥ 2.4
# because of (generator expression) and itertools.groupby, sorted

import itertools

def sort_uniq(sequence):
    return (x[0] for x in itertools.groupby(sorted(sequence)))

更快:

1
2
3
4
5
6
7
8
9
10
11
12
import itertools, operator
import sys

if sys.hexversion < 0x03000000:
    mapper= itertools.imap # 2.4 ≤ Python < 3
else:
    mapper= map # Python ≥ 3

def sort_uniq(sequence):
    return mapper(
        operator.itemgetter(0),
        itertools.groupby(sorted(sequence)))

两个版本都返回一个生成器,因此您可能希望将结果提供给列表类型:

1
sequence= list(sort_uniq(sequence))

请注意,这也适用于非哈希项:

1
2
>>> list(sort_uniq([[0],[1],[0]]))
[[0], [1]]


直接的解决方案由ignacio-sorted(set(foo))提供。

如果您有唯一的数据,那么有一个合理的机会,您不只是想执行sorted(set(...)),而是一直存储一个集合,偶尔提取一个经过排序的值版本。(到那时,它开始听起来像人们经常使用的数据库。)

如果您有一个已排序的列表,并且希望检查对数的成员资格,并在最坏情况下线性时间添加一个项目,则可以使用bisect模块。

如果您希望一直保持这种状态,并且希望简化操作或使某些操作执行得更好,那么可以考虑使用blist.sortedset


其他人提到了sorted(set(my_list)),它适用于字符串、数字和元组等可哈希值,但不适用于列表等不可哈希类型。

要获取任何可排序类型的值的排序列表,而不重复:

1
2
3
4
5
6
7
8
9
10
from itertools import izip, islice
def unique_sorted(values):
   "Return a sorted list of the given values, without duplicates."
    values = sorted(values)
    if not values:
        return []
    consecutive_pairs = izip(values, islice(values, 1, len(values)))
    result = [a for (a, b) in consecutive_pairs if a != b]
    result.append(values[-1])
    return result

这可以使用ITertools文档中的"pairwise"或"unique-justseen"配方进一步简化。


不能说这是一种干净的方式,但只是为了好玩:

1
my_list = [x for x in sorted(my_list) if not x in locals()["_[1]"]]