[python] 두 목록의 차이를 얻으십시오

파이썬에는 다음과 같은 두 가지 목록이 있습니다.

temp1 = ['One', 'Two', 'Three', 'Four']
temp2 = ['One', 'Two']

두 번째 목록에는없는 첫 번째 목록의 항목으로 세 번째 목록을 만들어야합니다. 예제에서 나는 얻어야한다.

temp3 = ['Three', 'Four']

주기와 점검이없는 빠른 방법이 있습니까?



답변

In [5]: list(set(temp1) - set(temp2))
Out[5]: ['Four', 'Three']

조심해

In [5]: set([1, 2]) - set([2, 3])
Out[5]: set([1]) 

당신이 그것을 기대하거나 원할 수도있는 곳 set([1, 3]). set([1, 3])답을 원한다면 을 사용해야 set([1, 2]).symmetric_difference(set([2, 3]))합니다.


답변

기존 솔루션은 모두 다음 중 하나를 제공합니다.

  • O (n * m) 성능보다 빠릅니다.
  • 입력 목록의 순서를 유지하십시오.

그러나 지금까지 해결책이 없습니다. 둘 다 원하는 경우 다음을 시도하십시오.

s = set(temp2)
temp3 = [x for x in temp1 if x not in s]

성능 테스트

import timeit
init = 'temp1 = list(range(100)); temp2 = [i * 2 for i in range(50)]'
print timeit.timeit('list(set(temp1) - set(temp2))', init, number = 100000)
print timeit.timeit('s = set(temp2);[x for x in temp1 if x not in s]', init, number = 100000)
print timeit.timeit('[item for item in temp1 if item not in temp2]', init, number = 100000)

결과 :

4.34620224079 # ars' answer
4.2770634955  # This answer
30.7715615392 # matt b's answer

순서를 유지하는 것뿐만 아니라 내가 제시 한 방법은 불필요한 세트의 구성이 필요하지 않기 때문에 세트 빼기보다 (약간) 빠릅니다. 첫 번째 목록이 두 번째 목록보다 상당히 길고 해싱이 비싸면 성능 차이가 더 두드러집니다. 이를 입증하는 두 번째 테스트는 다음과 같습니다.

init = '''
temp1 = [str(i) for i in range(100000)]
temp2 = [str(i * 2) for i in range(50)]
'''

결과 :

11.3836875916 # ars' answer
3.63890368748 # this answer (3 times faster!)
37.7445402279 # matt b's answer


답변

temp3 = [item for item in temp1 if item not in temp2]


답변

두 목록 (예 : list1과 list2)의 차이점은 다음과 같은 간단한 기능을 사용하여 찾을 수 있습니다.

def diff(list1, list2):
    c = set(list1).union(set(list2))  # or c = set(list1) | set(list2)
    d = set(list1).intersection(set(list2))  # or d = set(list1) & set(list2)
    return list(c - d)

또는

def diff(list1, list2):
    return list(set(list1).symmetric_difference(set(list2)))  # or return list(set(list1) ^ set(list2))

상기 기능을 이용하여, 차이가 사용 찾을 수 diff(temp2, temp1)또는 diff(temp1, temp2). 둘 다 결과를 줄 것이다 ['Four', 'Three']. 리스트의 순서 나 어떤리스트가 먼저 주어질 지 걱정할 필요가 없습니다.

파이썬 문서 참조


답변

차이를 재귀 적으로 원한다면 파이썬 패키지를 작성했습니다 :
https://github.com/seperman/deepdiff

설치

PyPi에서 설치 :

pip install deepdiff

사용법 예

가져 오기

>>> from deepdiff import DeepDiff
>>> from pprint import pprint
>>> from __future__ import print_function # In case running on Python 2

동일한 객체가 비어 있음

>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = t1
>>> print(DeepDiff(t1, t2))
{}

아이템 유형이 변경되었습니다

>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = {1:1, 2:"2", 3:3}
>>> pprint(DeepDiff(t1, t2), indent=2)
{ 'type_changes': { 'root[2]': { 'newtype': <class 'str'>,
                                 'newvalue': '2',
                                 'oldtype': <class 'int'>,
                                 'oldvalue': 2}}}

아이템의 가치가 변경되었습니다

>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = {1:1, 2:4, 3:3}
>>> pprint(DeepDiff(t1, t2), indent=2)
{'values_changed': {'root[2]': {'newvalue': 4, 'oldvalue': 2}}}

아이템 추가 및 / 또는 제거

>>> t1 = {1:1, 2:2, 3:3, 4:4}
>>> t2 = {1:1, 2:4, 3:3, 5:5, 6:6}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff)
{'dic_item_added': ['root[5]', 'root[6]'],
 'dic_item_removed': ['root[4]'],
 'values_changed': {'root[2]': {'newvalue': 4, 'oldvalue': 2}}}

문자열 차이

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world"}}
>>> t2 = {1:1, 2:4, 3:3, 4:{"a":"hello", "b":"world!"}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'values_changed': { 'root[2]': {'newvalue': 4, 'oldvalue': 2},
                      "root[4]['b']": { 'newvalue': 'world!',
                                        'oldvalue': 'world'}}}

문자열 차이 2

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world!\nGoodbye!\n1\n2\nEnd"}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world\n1\n2\nEnd"}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'values_changed': { "root[4]['b']": { 'diff': '--- \n'
                                                '+++ \n'
                                                '@@ -1,5 +1,4 @@\n'
                                                '-world!\n'
                                                '-Goodbye!\n'
                                                '+world\n'
                                                ' 1\n'
                                                ' 2\n'
                                                ' End',
                                        'newvalue': 'world\n1\n2\nEnd',
                                        'oldvalue': 'world!\n'
                                                    'Goodbye!\n'
                                                    '1\n'
                                                    '2\n'
                                                    'End'}}}

>>>
>>> print (ddiff['values_changed']["root[4]['b']"]["diff"])
---
+++
@@ -1,5 +1,4 @@
-world!
-Goodbye!
+world
 1
 2
 End

타입 변경

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world\n\n\nEnd"}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'type_changes': { "root[4]['b']": { 'newtype': <class 'str'>,
                                      'newvalue': 'world\n\n\nEnd',
                                      'oldtype': <class 'list'>,
                                      'oldvalue': [1, 2, 3]}}}

차이점

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3, 4]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{'iterable_item_removed': {"root[4]['b'][2]": 3, "root[4]['b'][3]": 4}}

목록 차이 2 :

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 3, 2, 3]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'iterable_item_added': {"root[4]['b'][3]": 3},
  'values_changed': { "root[4]['b'][1]": {'newvalue': 3, 'oldvalue': 2},
                      "root[4]['b'][2]": {'newvalue': 2, 'oldvalue': 3}}}

순서를 무시하거나 중복을 무시하는 차이점을 나열하십시오. (위와 동일한 사전으로)

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 3, 2, 3]}}
>>> ddiff = DeepDiff(t1, t2, ignore_order=True)
>>> print (ddiff)
{}

사전이 포함 된 목록 :

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, {1:1, 2:2}]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, {1:3}]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'dic_item_removed': ["root[4]['b'][2][2]"],
  'values_changed': {"root[4]['b'][2][1]": {'newvalue': 3, 'oldvalue': 1}}}

세트 :

>>> t1 = {1, 2, 8}
>>> t2 = {1, 2, 3, 5}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (DeepDiff(t1, t2))
{'set_item_added': ['root[3]', 'root[5]'], 'set_item_removed': ['root[8]']}

명명 된 튜플 :

>>> from collections import namedtuple
>>> Point = namedtuple('Point', ['x', 'y'])
>>> t1 = Point(x=11, y=22)
>>> t2 = Point(x=11, y=23)
>>> pprint (DeepDiff(t1, t2))
{'values_changed': {'root.y': {'newvalue': 23, 'oldvalue': 22}}}

맞춤 객체 :

>>> class ClassA(object):
...     a = 1
...     def __init__(self, b):
...         self.b = b
...
>>> t1 = ClassA(1)
>>> t2 = ClassA(2)
>>>
>>> pprint(DeepDiff(t1, t2))
{'values_changed': {'root.b': {'newvalue': 2, 'oldvalue': 1}}}

객체 속성이 추가되었습니다.

>>> t2.c = "new attribute"
>>> pprint(DeepDiff(t1, t2))
{'attribute_added': ['root.c'],
 'values_changed': {'root.b': {'newvalue': 2, 'oldvalue': 1}}}


답변

파이썬 XOR 연산자를 사용하여 수행 할 수 있습니다.

  • 이것은 각 목록에서 중복을 제거합니다
  • temp1과 temp1의 차이와 temp1과 temp2의 차이를 보여줍니다.

set(temp1) ^ set(temp2)


답변

가장 간단한 방법은

set ()을 사용하십시오 .difference (set ())

list_a = [1,2,3]
list_b = [2,3]
print set(list_a).difference(set(list_b))

대답은 set([1])

목록으로 인쇄 할 수 있고

print list(set(list_a).difference(set(list_b)))