使用 Python 的 list(set(list(...))) 去除重复项

8

是否

list(set(some_list))

如何从列表中删除重复项?(如果有影响,使用Python 3.3)

(编辑以回应一些评论...之前可能过于简洁)。

具体来说,

  • 它的效率(主要是速度,但也包括内存)至少与编写自己的算法相当吗?显然,这是最简洁的代码
  • 它是否可靠?是否存在任何导致其失败的情况? (已经提到了一个问题...列表项需要是可哈希的)
  • 有没有更像Python的方法呢?

4
你们用什么指标来判断好坏?有哪些替代方案可以进行比较?这是基于时间复杂度和/或内存消耗吗? - metatoaster
2
如果列表项不可哈希,则无法进行操作。 - chepner
4
你是否需要保持列表中物品的顺序? - Patrick Maupin
1
如果set对你的元素进行排序,那只是偶然。你不应该依赖它。 - Mark Ransom
2
@EelkeSpaak 这值得一份答案。 - Mark Ransom
显示剩余6条评论
3个回答

5

你展示的方法可能是最简单易懂的,这使它符合大多数Pythonic的定义。

如果你需要保留列表的顺序,你可以使用collections.OrderedDict代替set:

list(collections.OrderedDict((k, None) for k in some_list).keys())

编辑:自Python 3.7(或3.6,如果你信任)起,使用OrderedDict已不再必要;常规的dict具有保留插入顺序的特性。因此,您可以重写上述内容为:
list({k: None for k in some_list}.keys())

如果元素不可哈希但可以排序,您可以使用itertools.groupby来去除重复项:
list(k for k,g in itertools.groupby(sorted(some_list)))

编辑:上面的内容可以用列表推导式来写,有些人可能认为这更符合 Python 的风格。
[k for k,_ in itertools.groupby(sorted(some_list))]

4

(根据评论的建议,我把这个评论也作为回答。)

你自己的解决方案看起来很不错,而且非常符合Python的编程风格。如果你正在使用Numpy,你还可以这样做:new_list = numpy.unique(some_list)。这个代码几乎“像一句话一样阅读”,这是我认为一个好的“Pythonic”的标准。


1
为了保持顺序,最短的方式(从Python 2.7开始)是:
>>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys('abracadabra'))
['a', 'b', 'r', 'c', 'd']

如果不需要保留顺序,list(set(...)) 就可以了。

1
我不知道 fromkeys,而且我忘了 list 只会返回键。你的答案比我的简单多了,点赞。 - Mark Ransom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接