IT박스

파이썬은 한 목록에서 다른 목록에없는 요소를 찾습니다.

itboxs 2020. 9. 23. 07:25
반응형

파이썬은 한 목록에서 다른 목록에없는 요소를 찾습니다.


한 목록에는 있지만 다른 목록에는없는 특정 요소의 새 목록을 만들려면 두 목록을 비교해야합니다. 예를 들면 :

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 lists or sets (even with sets 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내 요구 사항을 완벽하게 충족합니다. 정보에 대한 답변입니다.

참고 URL : https://stackoverflow.com/questions/41125909/python-find-elements-in-one-list-that-are-not-in-the-other

반응형