파이썬은 한 목록에서 다른 목록에없는 요소를 찾습니다.
한 목록에는 있지만 다른 목록에는없는 특정 요소의 새 목록을 만들려면 두 목록을 비교해야합니다. 예를 들면 :
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) NumPy의 setdiff1d
. Chinny84 의 응답 에서 고유 요소에 관심이 있다면 다음을 수행하십시오.
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)
(2) 그렇지 않으면 main_list = np.setdiff1d(list_2,list_1, assume_unique=True)
두 가지 대답 모두 당신에게 줄 것 ["f", "m"]
입니다. 그러나 만약 list_2 = ["a", "f", "c", "m", "m"]
, 대답 (1)은 산출 ["f", "m"]
하지만 대답 (2)는 ["f", "m", "m"]
(의 각 요소의 고유성 list_2
이 중요하지 않기 때문에 ) 제공합니다 .
세트를 사용할 수 있습니다.
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))
This takes advantage of the functional functions taking a callback function on construction, allowing it to create the callback once and reuse it for every element without needing to store it somewhere (because filterfalse
stores it internally); list comprehensions and generator expressions can do this, but it's ugly.†
That gets the same results in a single line as:
main_list = [x for x in list_2 if x not in list_1]
with the speed of:
set_1 = set(list_1)
main_list = [x for x in list_2 if x not in set_1]
Of course, if the comparisons are intended to be positional, so:
list_1 = [1, 2, 3]
list_2 = [2, 3, 4]
should produce:
main_list = [2, 3, 4]
(because value in list_2
has a match at the same index in list_1
), you should definitely go with Patrick's answer, which involves no temporary list
s or set
s (even with set
s being roughly O(1)
, they have a higher "constant" factor per check than simple equality checks) and involves O(min(n, m))
work, less than any other answer, and if your problem is position sensitive, is the only correct solution when matching elements appear at mismatched offsets.
†: The way to do the same thing with a list comprehension as a one-liner would be to abuse nested looping to create and cache value(s) in the "outermost" loop, e.g.:
main_list = [x for set_1 in (set(list_1),) for x in list_2 if x not in set_1]
which also gives a minor performance benefit on Python 3 (because now set_1
is locally scoped in the comprehension code, rather than looked up from nested scope for each check; on Python 2 that doesn't matter, because Python 2 doesn't use closures for list comprehensions; they operate in the same scope they're used in).
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)
output:
['f', 'm']
I would zip
the lists together to compare them element by element.
main_list = [b for a, b in zip(list1, list2) if a!= b]
If the number of occurences should be taken into account you probably need to use something like collections.Counter
:
list_1=["a", "b", "c", "d", "e"]
list_2=["a", "f", "c", "m"]
from collections import Counter
cnt1 = Counter(list_1)
cnt2 = Counter(list_2)
final = [key for key, counts in cnt2.items() if cnt1.get(key, 0) != counts]
>>> final
['f', 'm']
As promised this can also handle differing number of occurences as "difference":
list_1=["a", "b", "c", "d", "e", 'a']
cnt1 = Counter(list_1)
cnt2 = Counter(list_2)
final = [key for key, counts in cnt2.items() if cnt1.get(key, 0) != counts]
>>> final
['a', 'f', 'm']
From ser1 remove items present in ser2.
Input
ser1 = pd.Series([1, 2, 3, 4, 5]) ser2 = pd.Series([4, 5, 6, 7, 8])
Solution
ser1[~ser1.isin(ser2)]
두 가지 방법을 사용했고 한 가지 방법이 다른 방법보다 유용하다는 것을 알았습니다. 내 대답은 다음과 같습니다.
내 입력 데이터 :
crkmod_mpp = ['M13','M18','M19','M24']
testmod_mpp = ['M13','M14','M15','M16','M17','M18','M19','M20','M21','M22','M23','M24']
방법 1 : np.setdiff1d
이 방법은 위치를 유지하기 때문에 다른 방법보다 좋습니다.
test= list(np.setdiff1d(testmod_mpp,crkmod_mpp))
print(test)
['M15', 'M16', 'M22', 'M23', 'M20', 'M14', 'M17', 'M21']
방법 2 : 방법 1과 같은 답을 주지만 순서를 어지럽 힙니다.
test = list(set(testmod_mpp).difference(set(crkmod_mpp)))
print(test)
['POA23', 'POA15', 'POA17', 'POA16', 'POA22', 'POA18', 'POA24', 'POA21']
Method1은 np.setdiff1d
내 요구 사항을 완벽하게 충족합니다. 정보에 대한 답변입니다.
'IT박스' 카테고리의 다른 글
콜론 (:) 연산자는 무엇을합니까? (0) | 2020.09.23 |
---|---|
작업 표시 줄에 드롭 다운 항목을 추가하는 방법 (0) | 2020.09.23 |
Maven 어셈블리 플러그인에서 생성 한 전쟁 이름을 어떻게 변경할 수 있습니까? (0) | 2020.09.23 |
Msysgit bash는 Windows 7에서 끔찍하게 느립니다. (0) | 2020.09.22 |
시간을 형식으로 인쇄하는 방법 : 2009‐08‐10 18 : 17 : 54.811 (0) | 2020.09.22 |