2010-05-28 2 views
36

을 포함하는 파이썬 목록 my_list을 고려하십시오.Python 목록에서 sort + uniq를 수행하는 가장 깨끗한 방법은 무엇입니까?

uniquify의 가장 파이썬적인 방법은 무엇이며 목록을 정렬합니까?
(생각해 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

가능한 중복 [어떻게 파이썬 목록에서 중복을 제거하고 주문을 유지합니까?] (http://stackoverflow.com/questions/479897/how-to-remove-duplicates-from-python-list-and-keep-order) – sampablokuper

답변

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

참고 이는 해시 가능 유형에서만 작동하므로 목록에서 작동하지 않습니다. – taleinat

+0

'sort'(대개?)가 디스크를 계속 사용하는 동안 메모리에서 모든 것을 수행한다는 것을 언급 할 가치가 있습니다. 이것을 대용량의 데이터 덩어리에 적용하면'MemoryError'에서 실패합니다. 좋은 답변 :) –

+0

@ReutSharabani : 아니, 다른 'sort()'메서드가 작동하므로 추가 할당이 필요하지 않습니다. –

-4

는 그렇게 깨끗한 방법이지만, 단지 재미를 위해 말할 수 없다 :

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

이것은 추악하고, 마법적이고 불필요하게 이차적입니다. –

+0

물론, 재미 있었을뿐입니다. – andreypopp

5

똑 바른 솔루션 Ignacio- sorted(set(foo))에 의해 제공됩니다.

고유 한 데이터가있는 경우 sorted(set(...))을하고 싶지 않고 항상 세트를 저장하고 때로는 정렬 된 버전의 값을 추출 할 수있는 가능성이 있습니다. (그 시점에서 사람들은 자주 데이터베이스를 사용하는 것과 같은 소리를 내기 시작합니다.)

정렬 된 목록이 있고 로그에 대한 멤버십을 확인하고 최악의 선형 시간으로 항목을 추가하려면 bisect module을 사용할 수 있습니다.

항상이 상태를 유지하면서 작업을 단순화하거나 일부 작업의 성능을 향상 시키려면 blist.sortedset을 고려하십시오.

+0

[sortedcontainers] (http://www.grantjenks.com/docs/sortedcontainers/)를 고려하십시오. Blist 대신 [SortedSet] (http://www.grantjenks.com/docs/sortedcontainers/sortedset.html)을 참조하십시오. [빠름] (http://www.grantjenks.com/docs/sortedcontainers/performance.html)과 pure-Python입니다. – GrantJ

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 (...))는 중복입니다. –

+0

큰 데이터 덩어리가 있다고 가정 할 때 이것은 받아 들인 대답보다 훨씬 낫습니다. +1 –

+0

@TheDemz 파이썬 3이 지금보다 훨씬 평범하다는 점을 고려할 때 대답이 필요하다. 감사 – tzot

관련 문제