여러 목록에 포함 된 모든 값의 합집합을 만드는 Python 방식


84

목록 목록이 있습니다.

lists = [[1,4,3,2,4], [4,5]]

이 목록을 병합하고 모든 중복 항목을 제거하고 싶습니다. 즉, 집합 결합 연산을 적용합니다.

desired_result = [1, 2, 3, 4, 5]

이 작업을 수행하는 가장 쉬운 방법은 무엇입니까?

답변:


152

set.union 당신이 원하는 것을 :

>>> results_list = [[1,2,3], [1,2,4]]
>>> results_union = set().union(*results_list)
>>> print(results_union)
set([1, 2, 3, 4])

세 개 이상의 목록으로이 작업을 수행 할 수도 있습니다.


@sth, 예를 들어 감사하지만 실행하면 오류가 발생합니다. Traceback (가장 최근 호출 마지막) : File "so_example.py", 33 행, in? results_union = set (). union (* result_lists) TypeError : union ()은 정확히 하나의 인수 (3이 주어짐)를 취합니다
AJ.

1
@AJ : 문서에 따르면 ( docs.python.org/library/stdtypes.html#set.union ) union()Python 버전 2.6 이상에 대한 여러 인수 만 지원합니다. 이전 버전을 사용하는 것 같으므로 명시적인 루프를 사용해야 할 것입니다. total = set(); for x in results_list: total.update(x) (s /; / \ n /)
sth

2
두 번째 줄을results_union = set.union(*(set(el) for el in results_list))
Noel Evans

1
@ Jean-FrançoisFabre TypeError: descriptor 'union' requires a 'set' object but received a 'list'in python 3.6 atleast.
Paritosh Singh 19 년

1
사용하는 경우 set.union(*results_list)메서드 설명자를 수동으로 바인딩합니다. 즉, 첫 번째 요소 results_list를 "self"로 보냅니다 . 이로 인해 몇 가지 이상한 제한이 있습니다. 1. 제대로 입력하지 않습니다 (이제 첫 번째 요소는 집합 하위 클래스의 집합 또는 인스턴스 여야 함). 2. 빈 조합은 results_list오류가됩니다 (잘못된 결과-빈 값을 반환해야 함). 세트).
wim

12

Python 2.5를 사용하는 것 같기 때문에 ( 현재 프로덕션 버전 인! = 2.6 버전에 대해 A가 필요하다면 Q에 언급하는 것이 좋을 것입니다 .-) 결과, 나는 추천한다 :

import itertools

...

return list(set(itertools.chain(*result_list)))

itertools 는 일반적으로 반복자 (그리고 많은 종류의 시퀀스 또는 컬렉션에서)와 함께 작업 할 수있는 좋은 방법이며 익숙해 지길 진심으로 권장합니다. itertools.chain특히 여기 에 문서화되어 있습니다 .


+1 멋진 itertools패키지 에 담글 수있는 좋은 시간의 완벽한 예입니다 .
gotgenes

@Alex 감사합니다 ... 버전을 지정하고 버전에서 너무 뒤쳐진 것에 대한 비난을 제거하기 위해 내 질문을 편집했습니다. :) itertools를 살펴보고 제안에 감사드립니다.
AJ.

@AJ, 비난 없음, 우리 모두는 결국 그러한 제약 하에서 고통받을 수 있습니다 (그러나 미래의 Qs에서 지정하는 것을 기억하십시오!-); itertools.chain그건 그렇고, Python 2.4에서도 잘 작동합니다.
Alex Martelli

3

이 스타일을 따를 수도 있습니다

In [12]: a = ['Orange and Banana', 'Orange Banana']
In [13]: b = ['Grapes', 'Orange Banana']
In [14]: c = ['Foobanana', 'Orange and Banana']

In [20]: list(set(a) | set(b) | set(c))
Out[20]: ['Orange and Banana', 'Foobanana', 'Orange Banana', 'Grapes']

In [21]: list(set(a) & set(b) | set(c))
Out[21]: ['Orange and Banana', 'Foobanana', 'Orange Banana']    


0

나는 다음을 사용하여 교차로를 만들었으므로 세트가 필요하지 않습니다.

a, b= [[1,2,3], [1,2]]
s = filter( lambda x: x in b, a)

또는,

s = [ x for x in b if x in a ]

5
왜 "세트의 필요성을 피하고 싶습니까?" 이 목적을 위해 더 빠르고 명확합니다. 그리고 "x in a"는 목록을 실행할 때마다 목록을 통해 선형적이고 무차별 대입 검색을 수행합니다. 왝.
Peter Hansen

세트는 타입 캐스팅을 필요로하며, 선형 속도는 큰 N. 취급하지 않는 나쁘지 않다

3
"타입 캐스팅"? 파이썬에서? 언제부터? 세트는 기본적으로 키만있는 사전이며 해시 및 같음 비교를 사용합니다. 목록에서 "x in a"를 사용하면 동등성 비교도 수행됩니다. 타입 캐스팅에 대한 모든 것이 무엇입니까?
Peter Hansen

0

이해하기 :

[*{ j for i in lists for j in i }]

또는

[*functools.reduce(lambda x,y: {*x, *y}, lists)]

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.