2010-05-28 37 views
36

考慮一個包含['foo', 'foo', 'bar']的Python列表my_list在Python列表上進行sort和uniq的最簡潔的方法是什麼?

什麼是012th和排序清單最Python的方法?
(認爲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() 
+0

可能dupl [如何從Python列表中刪除重複項並保持順序?](http://stackoverflow.com/questions/479897/how-to-remove-duplicates-from-python-list-and-keep-order) – sampablokuper 2015-12-06 13:34:18

回答

73
my_list = sorted(set(my_list)) 
+9

注意這隻適用於可哈希類型,所以例如這不會在列表上工作。 – taleinat 2010-05-28 20:11:25

+0

值得一提的是,這會處理內存中的所有內容,而'sort'(通常?)知道要堅持光盤。如果你將這個應用到大塊數據上,它會在'MemoryError'上失敗。好的回答雖然:) – 2017-05-29 08:16:03

+0

@ReutSharabani:不同的是,'sort()'方法在原地運行,因此不需要額外的分配。 – 2017-05-29 11:09:58

-4

不能說這是乾淨的方式做到這一點,但只是爲了好玩:

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

這是醜陋的,神奇的,不必要的二次方。 – 2010-05-28 19:30:25

+0

當然,這只是爲了好玩,正如我所指出的。 – andreypopp 2010-06-03 16:53:01

5

直截了當的解決方案是通過Ignacio- sorted(set(foo))提供。

如果您有獨特的數據,那麼您不僅希望執行sorted(set(...))的合理機會,而是始終存儲一個集合並偶爾提取這些值的排序版本。 (在那一點上,它聽起來就像人們經常使用數據庫的那種東西)。

如果你有一個排序列表,你想檢查對數的成員資格,並添加一個項目在最壞情況下的線性時間,你可以使用​​。

如果您想始終保持這種狀態,並且想要簡化某些操作或使某些操作性能更好,那麼可以考慮使用blist.sortedset

+0

考慮[sortedcontainers](http://www.grantjenks.com/docs/sortedcontainers/)。 [SortedSet](http://www.grantjenks.com/docs/sortedcontainers/sortedset.html)而不是blist。它[更快](http://www.grantjenks.com/docs/sortedcontainers/performance.html)和純Python。 – GrantJ 2015-09-18 19:42:08

2

其他人提到了排序(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的「成對的」或「unique_justseen」配方可以進一步簡化。

10
# 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]] 
+1

如果你正在使用python3:Py3 map和Py2 itertools.imap做同樣的事情。 (在Py3中iter(map(...))是多餘的。) – 2013-10-28 10:59:31

+0

假設你有大量的數據,這比接受的答案要好得多。 +1 – 2017-05-29 08:14:43

+0

@TheDemz答案需要考慮到Python 3比現在更加普遍;謝謝 – tzot 2017-05-29 21:09:58

相關問題