2010-12-16 5 views
79

파이썬에 목록이 있습니다. 어떻게 값을 고유하게 만들 수 있습니까?목록을 만드는 방법은 파이썬에서 유일한 요소를 포함하고 있습니까?

+1

또는 주문을 유지하려는 경우 [this] (http://stackoverflow.com/questions/480214/). –

+0

질문 제목을 수정하십시오. 당신은 명부를 명료하게 말하는 것에 대해 말하는 것이 아닙니다. 목록 ** 아이템 **을 구별하는 것에 대해 이야기하고 있습니다. –

+1

왜 처음부터 목록이 필요합니까? 어쩌면 set() 또는 dict()로 충분할 수 있습니다. –

답변

161

가장 간단한 목록으로 다시 세트로 변환하는 것입니다 :이와

my_list = list(set(my_list)) 

한 가지 단점은이 순서를 보존하지 것입니다. 목록 대신에 집합이 더 나은 데이터 구조가 될지 고려해야 할 수도 있습니다. http://www.peterbe.com/plog/uniqifiers-benchmark에서

+0

내가 잘못되었거나 python3k 값이 있습니다. 지금은 정렬 된 원인이 보존됩니까? – Ant

+5

아니요, 그렇지 않습니다. –

+0

@Ant 사전 키 순서는 Python 3.6에서 유지되지만 "이 새 구현의 순서 보존 측면은 구현 세부 사항으로 간주되므로 의존해서는 안됩니다." 그들은 모두 해시에 기반을두고 있기 때문에 세트가 같을 것이라고 생각 하겠지만 언급되지 않았습니다. 분명히 아닙니다 : https://docs.python.org/3.6/whatsnew/3.6.html – Mark

2

:

def f5(seq, idfun=None): 
    # order preserving 
    if idfun is None: 
     def idfun(x): return x 
    seen = {} 
    result = [] 
    for item in seq: 
     marker = idfun(item) 
     # in old Python versions: 
     # if seen.has_key(marker) 
     # but in new ones: 
     if marker in seen: continue 
     seen[marker] = 1 
     result.append(item) 
    return result 
+1

그렇지 않습니까? 딕트 (dict) 라기보다는 본 세트를 사용하는 것이 합리적입니까? –

+0

Python에서는 집합과 dicts가 해시 테이블을 사용하여 작성되므로이 시나리오에서는 서로 바꿔 쓸 수 있습니다. 둘 다 동일한 작업 (중복 제한)을 제공하며 둘 다 동일한 실행 시간을가집니다. – brildum

+0

이 하나가 느린 발전기 버전이 훨씬 빠릅니다. –

9

이 순서 유지하려면 다음 목록의 모든 요소를 ​​사전 키로 사용할 수 있습니다 경우

l = [1, 1, 2, 2, 3] 
result = list() 
map(lambda x: not x in result and result.append(x), l) 
result 
# [1, 2, 3] 
+0

python 3.4에서 빈 목록을 반환합니다 !!! –

1

(즉 그들은 모두 해쉬이다)이 종종 빠릅니다.

def f(seq): # Order preserving 
    ''' Modified version of Dave Kirby solution ''' 
    seen = set() 
    return [x for x in seq if x not in seen and not seen.add(x)] 

확인이 까다로운 조금 여기 if x not in seen and not seen.add(x) 때문에, 지금은, 작동합니까 방법 : http://www.peterbe.com/plog/uniqifiers-benchmark

Python Programming FAQ

d = {} 
for x in mylist: 
    d[x] = 1 
mylist = list(d.keys()) 
21

수정 된 버전의 순서를 유지하려면

In [1]: 0 not in [1,2,3] and not print('add') 
add 
Out[1]: True 

왜 True를 반환합니까? 에서 '추가'

In [2]: 1 not in [1,2,3] and not print('add') 
Out[2]: False 

이 왜 인쇄 않습니다 [1]가 아니라에서 [2] :

In [3]: type(seen.add(10)) 
Out[3]: <type 'NoneType'> 

not None == True :하지만, 인쇄 (및 set.add)는 아무 것도 반환하지 않습니다? False and print('add')을 참조하십시오. 이미 두 번째 인수를 확인하지 않습니다. 두 번째 인수는 이미 알고 있으므로 두 인수가 모두 참인 경우에만 true를 반환합니다.

더 일반적인 버전이 더 읽기, 발전기 기반의 함수로 값을 변환 할 수있는 기능이 추가 순서없이

def f(seq, idfun=None): # Order preserving 
    return list(_f(seq, idfun)) 

def _f(seq, idfun=None): 
    ''' Originally proposed by Andrew Dalke ''' 
    seen = set() 
    if idfun is None: 
    for x in seq: 
     if x not in seen: 
     seen.add(x) 
     yield x 
    else: 
    for x in seq: 
     x = idfun(x) 
     if x not in seen: 
     seen.add(x) 
     yield x 

를 (더 빨리이다) :

def f(seq): # Not order preserving 
    return list(set(seq)) 
+0

"_f10"은 무엇입니까? – kn3l

+0

일종의 내부 도우미 함수 (코드에 버그가 있었고 _f10 대신 _f10 대신 2 행에 있어야 함, spotting을 주셔서 감사합니다) –

+1

awesome function .... 감사합니다 .... 내 하루를 저장했습니다! – Abhishek

0

가장 간단한 방법 것은 제거 보존 순서는 collections.OrderedDict (Python 2.7+)을 사용하는 것입니다.

from collections import OrderedDict 
d = OrderedDict() 
for x in mylist: 
    d[x] = True 
print d.iterkeys() 
4

방법에 대한 사전 함축? 대니의 코멘트 @으로

>>> mylist = [3, 2, 1, 3, 4, 4, 4, 5, 5, 3] 

>>> {x:1 for x in mylist}.keys() 
[1, 2, 3, 4, 5] 

편집 : 내 원래의 제안은 주문 키를 유지하지 않습니다.당신이 정렬 키가 필요한 경우, 시도 :

(광범위하게 테스트되지 않음) 요소의 첫 번째 발생에 의해 순서대로 요소를 유지
>>> from collections import OrderedDict 

>>> OrderedDict((x,1) for x in mylist).keys() 
[3, 2, 1, 4, 5] 

+0

이렇게하면 주문이 보존되지 않습니다. 사전 순서 (및 설정 순서)는 삽입 순서가 아니라 해싱 알고리즘에 의해 결정됩니다. OrderedDict 유형에 대한 사전 이해도의 영향에 대해서는 확신하지 못합니다. –

+0

@DannyStaple True. 정렬 된 출력이 필요한 경우 'OrderedDict'및 생성기를 사용하는 예제를 추가했습니다. – cod3monk3y

13

한 라이너를 보존하기 위해

list(OrderedDict.fromkeys([2,1,1,3])) 
당신이해야하지만

from collections import OrderedDict 
+2

OrderedDict.fromkeys (my_list) .keys() –

+0

@DannyStaple : 파이썬 2에서 작동하지만 파이썬 3에서는 어떤 목적으로는 괜찮을 수도있는 사전 키 뷰를 반환하지만, 예를 들어 인덱싱을 지원합니다. – Mark

+0

첫 번째 라이너가 작동합니다. aternative 형식은 odict_keys 형식을 반환하는데 이는 덜 유용하지만 목록으로 변환 할 수도 있습니다. –

7

나를 예를 들어 귀하에게 설명하게 :

파이썬 목록

>>> randomList = ["a","f", "b", "c", "d", "a", "c", "e", "d", "f", "e"] 

이 있고 그것에서 중복을 제거 할 경우.

>>> uniqueList = [] 

>>> for letter in randomList: 
    if letter not in uniqueList: 
     uniqueList.append(letter) 

>>> uniqueList 
['a', 'f', 'b', 'c', 'd', 'e'] 

이렇게하면 목록에서 중복을 제거 할 수 있습니다.

+0

+1 해쉬 가능하지만 __eq__ 함수가있는 유형에만 사용할 수있는 유일한 함수이기 때문에 (해시 가능 유형 인 경우 다른 솔루션 중 하나를 사용하십시오). 매우 큰 목록의 경우 속도가 느려집니다. – Claude

0

파이썬에서 집합의 특징은 집합의 데이터 항목이 정렬되어 있지 않고 중복이 허용되지 않는다는 점입니다. 이미 데이터 항목이 포함 된 집합에 데이터 항목을 추가하려고하면 파이썬은 단순히 데이터 항목을 무시합니다.

>>> l = ['a', 'a', 'bb', 'b', 'c', 'c', '10', '10', '8','8', 10, 10, 6, 10, 11.2, 11.2, 11, 11] 
>>> distinct_l = set(l) 
>>> print(distinct_l) 
set(['a', '10', 'c', 'b', 6, 'bb', 10, 11, 11.2, '8']) 
관련 문제