<질문>
a = [1,2,3,4,5]
b = [1,3,5,6]
c = a and b
print c
실제 출력:[1,3,5,6]
예상 출력:[1,3,5]
두 목록에서 부울 AND 연산(목록 교차)을 어떻게 달성할 수 있습니까?
<답변1>
순서가 중요하지 않고 중복에 대해 걱정할 필요가 없는 경우 교차 설정을 사용할 수 있습니다.
>>> a = [1,2,3,4,5]
>>> b = [1,3,5,6]
>>> list(set(a) & set(b))
[1, 3, 5]
<답변2>
list comprehension을 사용하는 것은 저에게 매우 분명한 것입니다. 성능에 대해서는 확실하지 않지만 최소한 목록에 남아 있습니다.
[x for x in a if x in b]
또는 "X 값이 B에 있는 경우 A에 있는 모든 x 값".
<답변3>
두 목록 중 더 큰 것을 집합으로 변환하면 다음을 사용하여 해당 집합과 반복 가능 항목의 교집합을 얻을 수 있습니다.intersection()
:
a = [1,2,3,4,5]
b = [1,3,5,6]
set(a).intersection(b)
<답변4>
더 큰 것에서 세트를 만드십시오.
_auxset = set(a)
그 다음에,
c = [x for x in b if x in _auxset]
당신이 원하는대로 할 것입니다 (보존b
의 주문이 아니라a
의 -- 반드시 보존할 수는 없습니다.둘 다) 하고 해빠른. (사용if x in a
목록 이해의 조건도 작동하므로 빌드할 필요가 없습니다._auxset
, 하지만 불행하게도 상당한 길이의 목록의 경우 훨씬 느릴 것입니다.)
목록의 순서를 유지하는 대신 결과를 정렬하려는 경우 더 깔끔한 방법은 다음과 같습니다.
c = sorted(set(a).intersection(b))
<답변5>
다음은 두 목록의 교집합을 찾는 목록 기반 및 집합 기반 방법 모두에 대한 타이밍 정보를 생성하는 Python 2/Python 3 코드입니다.
순수 목록 이해 알고리즘은 O(n^2)입니다.in
목록에는 선형 검색이 있습니다. 집합 기반 알고리즘은 집합 검색이 O(1)이고 집합 생성이 O(n)이므로 집합을 목록으로 변환하는 것도 O(n)이므로 집합 기반 알고리즘은 O(n)입니다. 그래서 충분히 큰N집합 기반 알고리즘은 더 빠르지만 소규모N세트를 생성하는 오버헤드로 인해 순수 목록 비교 알고리즘보다 속도가 느려집니다.
#!/usr/bin/env python
''' Time list- vs set-based list intersection
See http://stackoverflow.com/q/3697432/4014959
Written by PM 2Ring 2015.10.16
'''
from __future__ import print_function, division
from timeit import Timer
setup = 'from __main__ import a, b'
cmd_lista = '[u for u in a if u in b]'
cmd_listb = '[u for u in b if u in a]'
cmd_lcsa = 'sa=set(a);[u for u in b if u in sa]'
cmd_seta = 'list(set(a).intersection(b))'
cmd_setb = 'list(set(b).intersection(a))'
reps = 3
loops = 50000
def do_timing(heading, cmd, setup):
t = Timer(cmd, setup)
r = t.repeat(reps, loops)
r.sort()
print(heading, r)
return r[0]
m = 10
nums = list(range(6 * m))
for n in range(1, m + 1):
a = nums[:6*n:2]
b = nums[:6*n:3]
print('\nn =', n, len(a), len(b))
#print('\nn = %d\n%s %d\n%s %d' % (n, a, len(a), b, len(b)))
la = do_timing('lista', cmd_lista, setup)
lb = do_timing('listb', cmd_listb, setup)
lc = do_timing('lcsa ', cmd_lcsa, setup)
sa = do_timing('seta ', cmd_seta, setup)
sb = do_timing('setb ', cmd_setb, setup)
print(la/sa, lb/sa, lc/sa, la/sb, lb/sb, lc/sb)
산출
n = 1 3 2
lista [0.082171916961669922, 0.082588911056518555, 0.0898590087890625]
listb [0.069530963897705078, 0.070394992828369141, 0.075379848480224609]
lcsa [0.11858987808227539, 0.1188349723815918, 0.12825107574462891]
seta [0.26900982856750488, 0.26902294158935547, 0.27298116683959961]
setb [0.27218389511108398, 0.27459001541137695, 0.34307217597961426]
0.305460649521 0.258469975867 0.440838458259 0.301898526833 0.255455833892 0.435697630214
n = 2 6 4
lista [0.15915989875793457, 0.16000485420227051, 0.16551494598388672]
listb [0.13000702857971191, 0.13060092926025391, 0.13543915748596191]
lcsa [0.18650484085083008, 0.18742108345031738, 0.19513416290283203]
seta [0.33592700958251953, 0.34001994132995605, 0.34146714210510254]
setb [0.29436492919921875, 0.2953648567199707, 0.30039691925048828]
0.473793098554 0.387009751735 0.555194537893 0.540689066428 0.441652573672 0.633583767462
n = 3 9 6
lista [0.27657914161682129, 0.28098297119140625, 0.28311991691589355]
listb [0.21585917472839355, 0.21679902076721191, 0.22272896766662598]
lcsa [0.22559309005737305, 0.2271728515625, 0.2323150634765625]
seta [0.36382699012756348, 0.36453008651733398, 0.36750602722167969]
setb [0.34979605674743652, 0.35533690452575684, 0.36164689064025879]
0.760194128313 0.59330170819 0.62005595016 0.790686848184 0.61710008036 0.644927481902
n = 4 12 8
lista [0.39616990089416504, 0.39746403694152832, 0.41129183769226074]
listb [0.33485794067382812, 0.33914685249328613, 0.37850618362426758]
lcsa [0.27405810356140137, 0.2745978832244873, 0.28249192237854004]
seta [0.39211201667785645, 0.39234519004821777, 0.39317893981933594]
setb [0.36988520622253418, 0.37011313438415527, 0.37571001052856445]
1.01034878821 0.85398540833 0.698928091731 1.07106176249 0.905302334456 0.740927452493
n = 5 15 10
lista [0.56792402267456055, 0.57422614097595215, 0.57740211486816406]
listb [0.47309303283691406, 0.47619009017944336, 0.47628307342529297]
lcsa [0.32805585861206055, 0.32813096046447754, 0.3349759578704834]
seta [0.40036201477050781, 0.40322518348693848, 0.40548801422119141]
setb [0.39103078842163086, 0.39722800254821777, 0.43811702728271484]
1.41852623806 1.18166313332 0.819398061028 1.45237674242 1.20986133789 0.838951479847
n = 6 18 12
lista [0.77897095680236816, 0.78187918663024902, 0.78467702865600586]
listb [0.629547119140625, 0.63210701942443848, 0.63321495056152344]
lcsa [0.36563992500305176, 0.36638498306274414, 0.38175487518310547]
seta [0.46695613861083984, 0.46992206573486328, 0.47583580017089844]
setb [0.47616910934448242, 0.47661614418029785, 0.4850609302520752]
1.66818870637 1.34819326075 0.783028414812 1.63591241329 1.32210827369 0.767878297495
n = 7 21 14
lista [0.9703209400177002, 0.9734041690826416, 1.0182771682739258]
listb [0.82394003868103027, 0.82625699043273926, 0.82796716690063477]
lcsa [0.40975093841552734, 0.41210508346557617, 0.42286920547485352]
seta [0.5086359977722168, 0.50968098640441895, 0.51014018058776855]
setb [0.48688101768493652, 0.4879908561706543, 0.49204087257385254]
1.90769222837 1.61990115188 0.805587768483 1.99293236904 1.69228211566 0.841583309951
n = 8 24 16
lista [1.204819917678833, 1.2206029891967773, 1.258256196975708]
listb [1.014998197555542, 1.0206191539764404, 1.0343101024627686]
lcsa [0.50966787338256836, 0.51018595695495605, 0.51319599151611328]
seta [0.50310111045837402, 0.50556015968322754, 0.51335406303405762]
setb [0.51472997665405273, 0.51948785781860352, 0.52113485336303711]
2.39478683834 2.01748351664 1.01305257092 2.34068341135 1.97190418975 0.990165516871
n = 9 27 18
lista [1.511646032333374, 1.5133969783782959, 1.5639569759368896]
listb [1.2461750507354736, 1.254518985748291, 1.2613379955291748]
lcsa [0.5565330982208252, 0.56119203567504883, 0.56451296806335449]
seta [0.5966339111328125, 0.60275578498840332, 0.64791703224182129]
setb [0.54694414138793945, 0.5508568286895752, 0.55375313758850098]
2.53362406013 2.08867620074 0.932788243907 2.76380331728 2.27843203069 1.01753187594
n = 10 30 20
lista [1.7777848243713379, 2.1453688144683838, 2.4085969924926758]
listb [1.5070111751556396, 1.5202279090881348, 1.5779800415039062]
lcsa [0.5954139232635498, 0.59703707695007324, 0.60746097564697266]
seta [0.61563014984130859, 0.62125110626220703, 0.62354087829589844]
setb [0.56723213195800781, 0.57257509231567383, 0.57460403442382812]
2.88774814689 2.44791645689 0.967161734066 3.13413984189 2.6567803378 1.04968299523
Linux의 Debian 버전에서 Python 2.6.6을 실행하는 2GB RAM이 있는 2GHz 단일 코어 머신을 사용하여 생성되었습니다(Firefox는 백그라운드에서 실행).
다양한 알고리즘의 실제 속도는 두 소스 목록에 있는 요소의 비율에 따라 다르게 영향을 받기 때문에 이러한 수치는 대략적인 안내일 뿐입니다.
<답변6>
다음을 사용하여 기능적 방법을 얻을 수 있습니다.filter
그리고lambda
운영자.
list1 = [1,2,3,4,5,6]
list2 = [2,4,6,9,10]
>>> list(filter(lambda x:x in list1, list2))
[2, 4, 6]
편집: list1과 list 모두에 존재하는 x를 필터링하고 다음을 사용하여 차이점을 설정할 수도 있습니다.
>>> list(filter(lambda x:x not in list1, list2))
[9,10]
편집2: 파이썬3filter
필터 객체를 반환하고 이를 캡슐화합니다.list
출력 목록을 반환합니다.
<답변7>
a = [1,2,3,4,5]
b = [1,3,5,6]
c = list(set(a).intersection(set(b)))
꿈처럼 일해야 합니다. 그리고 가능하다면 이 모든 유형 변경을 피하기 위해 목록 대신 세트를 사용하십시오!
<답변8>
당신은 또한 사용할 수 있습니다numpy.intersect1d(ar1, ar2)
.
두 배열 모두에 있는 고유하고 정렬된 값을 반환합니다.
<답변9>
이렇게 하면 두 목록의 교집합을 얻고 공통 중복도 얻을 수 있습니다.
>>> from collections import Counter
>>> a = Counter([1,2,3,4,5])
>>> b = Counter([1,3,5,6])
>>> a &= b
>>> list(a.elements())
[1, 3, 5]
<답변10>
이것은 결과의 각 요소가 두 배열에 표시되는 횟수만큼 나타나야 하는 경우의 예입니다.
def intersection(nums1, nums2):
#example:
#nums1 = [1,2,2,1]
#nums2 = [2,2]
#output = [2,2]
#find first 2 and remove from target, continue iterating
target, iterate = [nums1, nums2] if len(nums2) >= len(nums1) else [nums2, nums1] #iterate will look into target
if len(target) == 0:
return []
i = 0
store = []
while i < len(iterate):
element = iterate[i]
if element in target:
store.append(element)
target.remove(element)
i += 1
return store
<답변11>
목록 목록이있는 경우map
편리합니다:
>>> lists = [[1, 2, 3], [2, 3, 4], [2, 3, 5]]
>>> set(lists.pop()).intersection(*map(set, lists))
{2, 3}
유사한 iterables에서 작동합니다.
>>> lists = ['ash', 'nazg']
>>> set(lists.pop()).intersection(*map(set, lists))
{'a'}
pop
목록이 비어 있으면 날아가므로 함수로 래핑할 수 있습니다.
def intersect_lists(lists):
try:
return set(lists.pop()).intersection(*map(set, lists))
except IndexError: # pop from empty list
return set()
<답변12>
늦을 수도 있지만 수동으로 해야 하는 경우(작동하는 모습 - 하하) 또는 모든 요소가 가능한 한 많이 표시되어야 하거나 고유해야 하는 경우에 대해 공유해야 한다고 생각했습니다. .
이에 대한 테스트도 작성되었습니다.
from nose.tools import assert_equal
'''
Given two lists, print out the list of overlapping elements
'''
def overlap(l_a, l_b):
'''
compare the two lists l_a and l_b and return the overlapping
elements (intersecting) between the two
'''
#edge case is when they are the same lists
if l_a == l_b:
return [] #no overlapping elements
output = []
if len(l_a) == len(l_b):
for i in range(l_a): #same length so either one applies
if l_a[i] in l_b:
output.append(l_a[i])
#found all by now
#return output #if repetition does not matter
return list(set(output))
else:
#find the smallest and largest lists and go with that
sm = l_a if len(l_a) len(l_b) else l_b
for i in range(len(sm)):
if sm[i] in lg:
output.append(sm[i])
#return output #if repetition does not matter
return list(set(output))
## Test the Above Implementation
a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
exp = [1, 2, 3, 5, 8, 13]
c = [4, 4, 5, 6]
d = [5, 7, 4, 8 ,6 ] #assuming it is not ordered
exp2 = [4, 5, 6]
class TestOverlap(object):
def test(self, sol):
t = sol(a, b)
assert_equal(t, exp)
print('Comparing the two lists produces')
print(t)
t = sol(c, d)
assert_equal(t, exp2)
print('Comparing the two lists produces')
print(t)
print('All Tests Passed!!')
t = TestOverlap()
t.test(overlap)
<답변13>
여기에 있는 대부분의 솔루션은 목록의 요소 순서를 고려하지 않고 목록을 세트처럼 취급합니다. 반면에 두 목록에 포함된 가장 긴 하위 시퀀스 중 하나를 찾으려면 다음 코드를 시도할 수 있습니다.
def intersect(a, b):
if a == [] or b == []:
return []
inter_1 = intersect(a[1:], b)
if a[0] in b:
idx = b.index(a[0])
inter_2 = [a[0]] + intersect(a[1:], b[idx+1:])
if len(inter_1) <= len(inter_2):
return inter_2
return inter_1
을 위한a=[1,2,3]
그리고b=[3,1,4,2]
이것은 반환[1,2]
오히려[1,2,3]
. 이러한 하위 시퀀스는 다음과 같이 고유하지 않습니다.[1]
,[2]
,[3]
에 대한 모든 솔루션입니다.a=[1,2,3]
그리고b=[3,2,1]
.
<답변14>
부울 AND가 교차로와 같이 두 목록에 모두 나타나는 항목을 의미하는 경우 Python의set
그리고frozenset
유형.
<답변15>
카운터를 사용할 수도 있습니다! 순서를 유지하지는 않지만 중복을 고려합니다.
>>> from collections import Counter
>>> a = [1,2,3,4,5]
>>> b = [1,3,5,6]
>>> d1, d2 = Counter(a), Counter(b)
>>> c = [n for n in d1.keys() & d2.keys() for _ in range(min(d1[n], d2[n]))]
>>> print(c)
[1,3,5]
<답변16>
튜플을 사용하고 교차하고 싶을 때
a=([1,2,3,4,5,20], [8,3,9,5,1,4,20])
for i in range(len(a)):
b=set(a[i-1]).intersection(a[i])
print(b)
{1, 3, 4, 5, 20}
'개발 > Python' 카테고리의 다른 글
[파이썬] 딕셔너리를 문자열로 변환하고 다시 변환하는 방법 (0) | 2023.01.22 |
---|---|
[파이썬] x축 또는 y축을 반전시키는 방법 (0) | 2023.01.22 |
[파이썬] os.path.join()이 작동하지 않는 이유? (0) | 2023.01.22 |
[파이썬] 딕셔너리에서 keys()와 values()는 항상 순서가 같을까? (0) | 2023.01.22 |