파이썬과 리턴 매치에서 두 목록을 비교하는 방법


380

두 개의 목록을 가져 와서 둘 다에 나타나는 값을 찾고 싶습니다.

a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]

returnMatches(a, b)

예를 들어을 반환 [5]합니다.


4
아래의 답변은 모두 나에게 잘못되었습니다. 두 목록 중 하나에서 숫자가 반복되면 어떻게되는지 알고 싶습니까? (?) 그 정보.
MH

답변:


486

가장 효율적인 방법은 아니지만 가장 확실한 방법은 다음과 같습니다.

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a) & set(b)
{5}

순서가 중요한 경우 다음과 같이 목록 이해를 통해 수행 할 수 있습니다.

>>> [i for i, j in zip(a, b) if i == j]
[5]

(순서-의미가 의미하는 동일한 크기의 목록에서만 작동합니다).


15
목록 이해가 반드시 더 빠른 옵션 일 필요 는 없습니다 . 더 큰 세트 (성능이 가장 중요 할 경우)의 비트 단위 비교 ( &) set(a).intersection(b)는 목록 이해보다 빠르거나 빠릅니다.
Joshmaker

24
주의해야 할 또 다른 참고 사항 : 목록 이해는 동일한 위치에서 두 값 모두에 나타나는 값을 찾습니다 (이는 SilentGhost가 "순서가 중요 함"을 의미 함). 설정된 교차점 솔루션은 다른 위치에서도 일치하는 항목을 찾습니다. 이 두 가지 다른 질문에 대한 답변입니다 ... (op의 질문은 그것이 요구하는대로 모호합니다)
drevicko

목록이 목록의 목록 인 경우이를 수행하는 방법 (예 : a = [[0,0], [1,0]] 및 b = [[2,3], [0,0]]
Schneems

3
첫 번째 예제의 시간 복잡성은 무엇입니까 set(a) & set(b)?
AdjunctProfessorFalcon

두 세트가 모두 비어 있고 비교가 통과 될 것으로 예상되는 경우에는 작동하지 않습니다. "(설정 (a)와 세트 (B)) 또는 (안하지 B)"로 변경 그래서
닐 맥길

395

set.intersection ()을 사용하면 빠르고 읽기 쉽습니다 .

>>> set(a).intersection(b)
set([5])

28
이 답변은 빠른 검색을 위해 목록 중 하나만 (짧은 쪽을 선호해야 함) 설정하고 다른 목록은 해당 항목을 찾아 탐색하므로 알고리즘 성능이 좋습니다.
u0b34a0f6ae

18
bool(set(a).intersection(b))대한 TrueFalse
하기 Akshay

6
이 답변은보다 유연하고 읽기 쉽습니다 . 사람들은 difference또는을 필요로하기 때문 union입니다.
Shihe Zhang

객체를 목록 요소로 사용하고 부분 일치 만 원하는 경우, 즉 일치하는 객체로 간주하기 위해 일부 속성 만 일치해야합니까?
CGFoX

.intersection()vs에 대한 성능 차이가 &있습니까?
brandonbanks

106

Lutz의 솔루션을 보여주는 빠른 성능 테스트가 가장 좋습니다.

import time

def speed_test(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        for x in xrange(5000):
            results = func(*args, **kwargs)
        t2 = time.time()
        print '%s took %0.3f ms' % (func.func_name, (t2-t1)*1000.0)
        return results
    return wrapper

@speed_test
def compare_bitwise(x, y):
    set_x = frozenset(x)
    set_y = frozenset(y)
    return set_x & set_y

@speed_test
def compare_listcomp(x, y):
    return [i for i, j in zip(x, y) if i == j]

@speed_test
def compare_intersect(x, y):
    return frozenset(x).intersection(y)

# Comparing short lists
a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]
compare_bitwise(a, b)
compare_listcomp(a, b)
compare_intersect(a, b)

# Comparing longer lists
import random
a = random.sample(xrange(100000), 10000)
b = random.sample(xrange(100000), 10000)
compare_bitwise(a, b)
compare_listcomp(a, b)
compare_intersect(a, b)

내 컴퓨터의 결과는 다음과 같습니다.

# Short list:
compare_bitwise took 10.145 ms
compare_listcomp took 11.157 ms
compare_intersect took 7.461 ms

# Long list:
compare_bitwise took 11203.709 ms
compare_listcomp took 17361.736 ms
compare_intersect took 6833.768 ms

분명히 인공 성능 테스트는 소금 한 알갱이로 수행해야하지만 set().intersection()답은 적어도 다른 솔루션 만큼 빠르며 가장 읽기 쉬운 것이기 때문에이 일반적인 문제에 대한 표준 솔루션이어야합니다.


세트는 실제로 반복을 제거하므로 제 경우에는 작동하지 않습니다
rgralma

@rgralma set는 기존 항목에서 새로 만들면 list원본에서 아무것도 제거되지 않습니다 list. 목록 내에서 중복을 처리하는 특수 로직을 원한다면 중복 처리 방법에 대한 답변이 필요하기 때문에 새로운 질문을해야한다고 생각합니다.
Joshmaker

67

나는 세트 기반 답변을 선호하지만 여하튼 작동하는 답변이 있습니다.

[x for x in a if x in b]

15

가장 쉬운 방법은 세트 를 사용하는 것입니다 .

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a) & set(b)
set([5])

15

빠른 방법 :

list(set(a).intersection(set(b)))

14
>>> s = ['a','b','c']   
>>> f = ['a','b','d','c']  
>>> ss= set(s)  
>>> fs =set(f)  
>>> print ss.intersection(fs)   
   **set(['a', 'c', 'b'])**  
>>> print ss.union(fs)        
   **set(['a', 'c', 'b', 'd'])**  
>>> print ss.union(fs)  - ss.intersection(fs)   
   **set(['d'])**

1
문자열이 포함 된 목록에는 허용되는 답변이 작동하지 않습니다. 이거에요
Antony

12

또한 공통 요소를 새 목록에 유지하여이를 시도 할 수 있습니다.

new_list = []
for element in a:
    if element in b:
        new_list.append(element)

5

중복을 원하십니까? 그렇지 않은 경우 대신 세트를 사용해야합니다.


>>> set([1, 2, 3, 4, 5]).intersection(set([9, 8, 7, 6, 5]))
set([5])

정말로리스트를 원한다면, java2s.com/Code/Python/List/Functiontointersecttwolists.htm >>> intersect ([1, 2, 3, 4, 5], [9, 8, 7, 6, 5]) [5 ]
티모시 프래 틀리

문서에 따르면 -... 더 읽기 쉬운 Set ( 'abc'). intersection ( 'cbs')을 선호하여 Set ( 'abc') & 'cbs'와 같은 오류가 발생하기 쉬운 구성을 배제합니다. - docs.python.org/library/sets.html
아론 뉴턴

5

객체가 깊이 1을 가지며 순서를 유지하는 목록 1 (lst1) 및 목록 2 (lst2)에 대한 목록 등식을 확인하는 좀 더 기능적인 방법은 다음과 같습니다.

all(i == j for i, j in zip(lst1, lst2))   

4
a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]

lista =set(a)
listb =set(b)   
print listb.intersection(lista)   
returnMatches = set(['5']) #output 

print " ".join(str(return) for return in returnMatches ) # remove the set()   

 5        #final output 

이 코드는 질문에 대답 할 수 있지만 문제를 해결하는 방법 및 / 또는 이유에 대한 추가 컨텍스트를 제공하면 답변의 장기적인 가치가 향상됩니다.
Donald Duck

4

itertools.product도 사용할 수 있습니다.

>>> common_elements=[]
>>> for i in list(itertools.product(a,b)):
...     if i[0] == i[1]:
...         common_elements.append(i[0])

3

당신이 사용할 수있는

def returnMatches(a,b):
       return list(set(a) & set(b))

3

당신이 사용할 수있는:

a = [1, 3, 4, 5, 9, 6, 7, 8]
b = [1, 7, 0, 9]
same_values = set(a) & set(b)
print same_values

산출:

set([1, 7, 9])

4
6 년 전의 답변과 어떻게 다릅니 까?
tmdavison

1
글쎄, 나는 출력과 함께 완전한 세부 사항을 썼고 초보자 파이썬을 위해 좋은
Adnan Ghaffar

2

부울 값을 원하는 경우 :

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(b) == set(a)  & set(b) and set(a) == set(a) & set(b)
False
>>> a = [3,1,2]
>>> b = [1,2,3]
>>> set(b) == set(a)  & set(b) and set(a) == set(a) & set(b)
True

1

다음 솔루션은 목록 항목의 순서에 관계없이 작동하며 두 목록의 길이가 다를 수도 있습니다.

import numpy as np
def getMatches(a, b):
    matches = []
    unique_a = np.unique(a)
    unique_b = np.unique(b)
    for a in unique_a:
        for b in unique_b:
            if a == b:
                matches.append(a)
    return matches
print(getMatches([1, 2, 3, 4, 5], [9, 8, 7, 6, 5, 9])) # displays [5]
print(getMatches([1, 2, 3], [3, 4, 5, 1])) # displays [1, 3]

1
Numpy는 다음과 같은 기능을 수행합니다.np.intersect1d(list1, list2)
obchardon

0

__and__속성 방법을 사용하면 작동합니다.

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a).__and__(set(b))
set([5])

또는 단순히

>>> set([1, 2, 3, 4, 5]).__and__(set([9, 8, 7, 6, 5]))
set([5])
>>>    

0
you can | for set union and & for set intersection.
for example:

    set1={1,2,3}
    set2={3,4,5}
    print(set1&set2)
    output=3

    set1={1,2,3}
    set2={3,4,5}
    print(set1|set2)
    output=1,2,3,4,5

curly braces in the answer.

4
질문은 목록에 대한 것이었고 설정되지 않았습니다. &set 에서 연산자의 사용 은 이미 허용 된 답변으로 SilentGhost에 의해 답변되었습니다
dWinder

0

방금 다음을 사용했으며 나를 위해 일했습니다.

group1 = [1, 2, 3, 4, 5]
group2 = [9, 8, 7, 6, 5]

for k in group1:
    for v in group2:
        if k == v:
            print(k)

그러면 귀하의 경우 5를 인쇄합니다. 아마 현명한 성능은 아닙니다.

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