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


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))대한 True나False
— 하기 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.