한 목록에는 있지만 다른 목록에는없는 특정 요소의 새 목록을 만들려면 두 목록을 비교해야합니다. 예를 들면 :
main_list=[]
list_1=["a", "b", "c", "d", "e"]
list_2=["a", "f", "c", "m"]
list_1을 반복하고 list_1에없는 list_2의 모든 요소를 main_list에 추가하고 싶습니다.
결과는 다음과 같아야합니다.
main_list=["f", "m"]
파이썬으로 어떻게 할 수 있습니까?
답변
요약 :
솔루션 (1)
import numpy as np
main_list = np.setdiff1d(list_2,list_1)
# yields the elements in `list_2` that are NOT in `list_1`
해결책 (2) 정렬 된 목록을 원합니다
def setdiff_sorted(array1,array2,assume_unique=False):
ans = np.setdiff1d(array1,array2,assume_unique).tolist()
if assume_unique:
return sorted(ans)
return ans
main_list = setdiff_sorted(list_2,list_1)
설명은 :
(1) 당신은 NumPy와의를 사용할 수 있습니다 setdiff1d
( array1
, array2
, assume_unique
= False
).
assume_unique
배열이 이미 고유한지 여부를 사용자에게 묻습니다.
인 경우 False
고유 요소가 먼저 결정됩니다.
이면 True
함수는 요소가 이미 고유하다고 가정하고 함수는 고유 요소 결정을 건너 뜁니다.
이러한 수율 고유 한 값 array1
이이 없습니다 에 array2
. assume_unique
이다 False
기본적으로.
고유 한 요소 ( Chinny84 의 응답을 기반으로 함)에 관심이 있다면 간단히 (여기서 assume_unique=False
=> 기본값)을 사용하십시오.
import numpy as np
list_1 = ["a", "b", "c", "d", "e"]
list_2 = ["a", "f", "c", "m"]
main_list = np.setdiff1d(list_2,list_1)
# yields the elements in `list_2` that are NOT in `list_1`
(2)
답변을 정렬하고 싶은 분들을 위해 커스텀 함수를 만들었습니다.
import numpy as np
def setdiff_sorted(array1,array2,assume_unique=False):
ans = np.setdiff1d(array1,array2,assume_unique).tolist()
if assume_unique:
return sorted(ans)
return ans
답을 얻으려면 다음을 실행하십시오.
main_list = setdiff_sorted(list_2,list_1)
참고 사항 :
(a) 솔루션 2 (사용자 지정 함수 setdiff_sorted
)는 목록을 반환 합니다 ( 솔루션 1 의 배열 과 비교 ).
(b) 요소가 고유한지 확실하지 않은 경우 setdiff1d
솔루션 A와 B 모두에서 NumPy의 기본 설정을 사용하십시오 . 합병증의 예는 무엇입니까? 참고 (c)를 참조하십시오.
(c) 두 목록 중 하나가 고유 하지 않으면 상황이 달라집니다 .
고유하지 않은
말 list_2
: list2 = ["a", "f", "c", "m", "m"]
. 있는 그대로 유지 list1
: 수율 list_1 = ["a", "b", "c", "d", "e"]
기본값 설정 (두 솔루션 모두). 그러나을 설정 하면 두 솔루션 모두 . 왜? 이는 사용자가 요소가 고유하다고 가정했기 때문입니다.) 따라서 유지하는 것이 좋습니다assume_unique
["f", "m"]
assume_unique=True
["f", "m", "m"]
assume_unique
기본값으로. 두 답변이 모두 정렬되어 있습니다.
답변
세트를 사용할 수 있습니다.
main_list = list(set(list_2) - set(list_1))
산출:
>>> list_1=["a", "b", "c", "d", "e"]
>>> list_2=["a", "f", "c", "m"]
>>> set(list_2) - set(list_1)
set(['m', 'f'])
>>> list(set(list_2) - set(list_1))
['m', 'f']
@JonClements의 의견에 따라 다음은 더 깔끔한 버전입니다.
>>> list_1=["a", "b", "c", "d", "e"]
>>> list_2=["a", "f", "c", "m"]
>>> list(set(list_2).difference(list_1))
['m', 'f']
답변
네이티브 메서드를 사용할 수있을 때 위의 설명이 왜 그렇게 복잡한 지 잘 모르겠습니다.
main_list = list(set(list_2)-set(list_1))
답변
다음 과 같이 목록 이해력을 사용하십시오 .
main_list = [item for item in list_2 if item not in list_1]
산출:
>>> list_1 = ["a", "b", "c", "d", "e"]
>>> list_2 = ["a", "f", "c", "m"]
>>>
>>> main_list = [item for item in list_2 if item not in list_1]
>>> main_list
['f', 'm']
편집하다:
아래 주석에서 언급했듯이 큰 목록으로 위의 방법은 이상적인 솔루션이 아닙니다. 이 경우 더 나은 옵션은 첫 번째 로 변환 list_1
하는 것입니다 set
.
set_1 = set(list_1) # this reduces the lookup time from O(n) to O(1)
main_list = [item for item in list_2 if item not in set_1]
답변
당신은 단지 필요로하는 한 줄 용액 (수입 무시)하려면 O(max(n, m))
길이의 입력에 대한 작업을 n
하고 m
,하지 O(n * m)
작업을, 당신은에 그렇게 할 수 모듈 :itertools
from itertools import filterfalse
main_list = list(filterfalse(set(list_1).__contains__, list_2))
이는 생성시 콜백 함수를 사용하는 기능적 함수를 활용하여 콜백을 한 번 생성하고 어딘가에 저장할 필요없이 모든 요소에 대해 재사용 할 수 있도록합니다 ( filterfalse
내부적으로 저장하기 때문 ). 목록 이해력과 생성기 표현이이 작업을 수행 할 수 있지만보기 흉합니다. †
한 줄에 다음과 같은 결과가 나타납니다.
main_list = [x for x in list_2 if x not in list_1]
속도 :
set_1 = set(list_1)
main_list = [x for x in list_2 if x not in set_1]
물론 비교가 위치를 기준으로한다면 다음과 같습니다.
list_1 = [1, 2, 3]
list_2 = [2, 3, 4]
다음을 생성해야합니다.
main_list = [2, 3, 4]
(의 값 list_2
이의 동일한 인덱스에서 일치 하기 때문에 list_1
), 임시 s 또는 s 를 포함하지 않는 패트릭의 대답 을 선택해야합니다 ( s가 대략 인 경우에도 간단한 동등성 검사보다 검사 당 더 높은 “상수”계수를가집니다. ) 및 작업이 다른 어떤 대답보다 적으며 문제가 위치에 민감한 경우 일치하는 요소가 일치하지 않는 오프셋에 나타날 때 유일한 올바른 해결책입니다.list
set
set
O(1)
O(min(n, m))
† : 한 줄로 된 목록 이해력으로 동일한 작업을 수행하는 방법은 중첩 된 루프를 남용하여 “가장 바깥 쪽”루프에서 값을 만들고 캐시하는 것입니다. 예 :
main_list = [x for set_1 in (set(list_1),) for x in list_2 if x not in set_1]
이는 또한 Python 3에서 약간의 성능 이점을 제공합니다 (이제 set_1
각 검사에 대해 중첩 된 범위에서 조회하는 것이 아니라 이해 코드에서 로컬 범위로 지정되기 때문입니다. Python 2에서는 Python 2에서 클로저를 사용하지 않기 때문에 list comprehensions; 그들은 그들이 사용되는 것과 같은 범위에서 작동합니다).
답변
main_list=[]
list_1=["a", "b", "c", "d", "e"]
list_2=["a", "f", "c", "m"]
for i in list_2:
if i not in list_1:
main_list.append(i)
print(main_list)
산출:
['f', 'm']
답변
나는 zip
목록을 함께 요소별로 비교할 것입니다.
main_list = [b for a, b in zip(list1, list2) if a!= b]