在Python列表上进行排序加uniq的最简洁方法是什么?

时间:2010-05-28 18:46:49

标签: python unique

考虑包含my_list

的Python列表['foo', 'foo', 'bar']

uniquify最常用的Pythonic方法是什么?对列表进行排序? (想想cat my_list | sort | uniq

这就是我目前的做法,虽然它有效,但我确信有更好的方法可以做到。

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()

5 个答案:

答案 0 :(得分:90)

my_list = sorted(set(my_list))

答案 1 :(得分:14)

# 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)))

更快:

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)))

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

sequence= list(sort_uniq(sequence))

请注意,这也适用于不可清洗的项目:

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

答案 2 :(得分:5)

直接解决方案由Ignacio提供 - sorted(set(foo))

如果你有独特的数据,你有可能不仅想要sorted(set(...))而是一直存储一组,偶尔也会抽出一个排序版本的值。 (此时,它开始听起来像人们经常使用数据库的那种东西。)

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

如果您希望始终保持这种状态并希望简化操作或使某些操作表现更好,您可以考虑blist.sortedset

答案 3 :(得分:2)

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

获取任何可排序类型的值的排序列表,没有重复:

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 documentation中的“pairwise”或“unique_justseen”配方可以进一步简化。

答案 4 :(得分:-5)

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

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