파이썬에서 두 목록의 차이점을 계산하는 가장 좋은 방법은 무엇입니까?
예
A = [1,2,3,4]
B = [2,5]
A - B = [1,3,4]
B - A = [5]
답변
set
품목 주문이나 반복에 신경 쓰지 않는다면 사용하십시오 . 다음과 같은 경우 목록 이해를 사용하십시오 .
>>> def diff(first, second):
second = set(second)
return [item for item in first if item not in second]
>>> diff(A, B)
[1, 3, 4]
>>> diff(B, A)
[5]
>>>
답변
순서가 중요하지 않은 경우 설정된 차이를 간단히 계산할 수 있습니다.
>>> set([1,2,3,4]) - set([2,5])
set([1, 4, 3])
>>> set([2,5]) - set([1,2,3,4])
set([5])
답변
당신은 할 수 있습니다
list(set(A)-set(B))
과
list(set(B)-set(A))
답변
짧막 한 농담:
diff = lambda l1,l2: [x for x in l1 if x not in l2]
diff(A,B)
diff(B,A)
또는:
diff = lambda l1,l2: filter(lambda x: x not in l2, l1)
diff(A,B)
diff(B,A)
답변
Python 2.7.3 (기본값, 2014 년 2 월 27 일 19:58:35)-IPython 1.1.0-timeit : (github gist)
def diff(a, b):
b = set(b)
return [aa for aa in a if aa not in b]
def set_diff(a, b):
return list(set(a) - set(b))
diff_lamb_hension = lambda l1,l2: [x for x in l1 if x not in l2]
diff_lamb_filter = lambda l1,l2: filter(lambda x: x not in l2, l1)
from difflib import SequenceMatcher
def squeezer(a, b):
squeeze = SequenceMatcher(None, a, b)
return reduce(lambda p,q: p+q, map(
lambda t: squeeze.a[t[1]:t[2]],
filter(lambda x:x[0]!='equal',
squeeze.get_opcodes())))
결과 :
# Small
a = range(10)
b = range(10/2)
timeit[diff(a, b)]
100000 loops, best of 3: 1.97 µs per loop
timeit[set_diff(a, b)]
100000 loops, best of 3: 2.71 µs per loop
timeit[diff_lamb_hension(a, b)]
100000 loops, best of 3: 2.1 µs per loop
timeit[diff_lamb_filter(a, b)]
100000 loops, best of 3: 3.58 µs per loop
timeit[squeezer(a, b)]
10000 loops, best of 3: 36 µs per loop
# Medium
a = range(10**4)
b = range(10**4/2)
timeit[diff(a, b)]
1000 loops, best of 3: 1.17 ms per loop
timeit[set_diff(a, b)]
1000 loops, best of 3: 1.27 ms per loop
timeit[diff_lamb_hension(a, b)]
1 loops, best of 3: 736 ms per loop
timeit[diff_lamb_filter(a, b)]
1 loops, best of 3: 732 ms per loop
timeit[squeezer(a, b)]
100 loops, best of 3: 12.8 ms per loop
# Big
a = xrange(10**7)
b = xrange(10**7/2)
timeit[diff(a, b)]
1 loops, best of 3: 1.74 s per loop
timeit[set_diff(a, b)]
1 loops, best of 3: 2.57 s per loop
timeit[diff_lamb_filter(a, b)]
# too long to wait for
timeit[diff_lamb_filter(a, b)]
# too long to wait for
timeit[diff_lamb_filter(a, b)]
# TypeError: sequence index must be integer, not 'slice'
@ roman-bodnarchuk 목록 이해 함수 def diff (a, b) 가 더 빠른 것 같습니다.
답변
위의 예는 차이를 계산하는 문제를 사소하게 만들었습니다. 정렬 또는 중복 제거를 가정하면 차이를 쉽게 계산할 수 있지만 비교에서 이러한 가정을 감당할 수없는 경우 diff 알고리즘을 간단하게 구현해야합니다. 파이썬 표준 라이브러리에서 difflib를 참조하십시오.
#! /usr/bin/python2
from difflib import SequenceMatcher
A = [1,2,3,4]
B = [2,5]
squeeze=SequenceMatcher( None, A, B )
print "A - B = [%s]"%( reduce( lambda p,q: p+q,
map( lambda t: squeeze.a[t[1]:t[2]],
filter(lambda x:x[0]!='equal',
squeeze.get_opcodes() ) ) ) )
산출:
A - B = [[1, 3, 4]]
답변
A = [1,2,3,4]
B = [2,5]
#A - B
x = list(set(A) - set(B))
#B - A
y = list(set(B) - set(A))
print x
print y