답변:
>>> L1 = [2,3,4]
>>> L2 = [1,2]
>>> [i for i in L1 if i in L2]
[2]
>>> S1 = set(L1)
>>> S2 = set(L2)
>>> S1.intersection(S2)
set([2])
빈 목록과 빈 세트는 모두 False이므로 값을 직접 진리 값으로 사용할 수 있습니다.
any
은 True
값을 찾 자마자 일찍 돌아올 수 있기 때문에 훨씬 더 빠릅니다 . 전체 목록을 먼저 작성할 필요가 없습니다.
아, 토비아스 당신이 날 이겼어요. 귀하의 솔루션 에서이 약간의 변형을 생각하고있었습니다.
>>> a = [1,2,3,4]
>>> b = [2,7]
>>> print(any(x in a for x in b))
True
x in long for x in short
vs x in short for x in long
)
a
과 b
길이가 같은 경우 max와 min은 가장 왼쪽 목록을 반환하여 any()
통화가 양쪽에서 동일한 목록으로 작동합니다. 길이를 반드시 확인해야하는 경우 두 번째 호출에서 목록 순서를 반대로하십시오 any(x in max(a, b, key=len) for x in (b, a, key=len))
.
any(x in max(a, b, key=len) for x in min(b, a, key=len))
(분을 놓쳤습니다).
아마도 좀 더 게으르다.
a = [1,2,3,4]
b = [2,7]
print any((True for x in a if x in b))
any
일찍 반환 할 수 있기 때문에 훨씬 빠릅니다. 버전은 any
사용 하기 전에 전체 목록을 이해해야 합니다. @ user89788의 답변은 이중 괄호가 불필요하기 때문에 약간 더 좋습니다
파이썬 3에서는 압축 풀기 별표를 사용할 수 있습니다. 두 가지 목록이 제공됩니다.
bool(len({*a} & {*b}))
편집 : 알칸 엔의 제안을 통합
"a가 b인지 확인하십시오"라고 생각하면 해시 (이 경우 설정)를 생각하십시오. 가장 빠른 방법은 확인하려는 목록을 해시 한 다음 각 항목을 확인하는 것입니다.
이것이 Joe Koberg의 답변이 빠른 이유입니다. 설정된 교차점 확인이 매우 빠릅니다.
데이터가 많지 않은 경우 세트를 만드는 것은 시간 낭비 일 수 있습니다. 따라서 목록 세트를 만들고 각 항목을 확인할 수 있습니다.
tocheck = [1,2] # items to check
a = [2,3,4] # the list
a = set(a) # convert to set (O(len(a)))
print [i for i in tocheck if i in a] # check items (O(len(tocheck)))
확인하려는 항목 수가 적 으면 차이를 무시할 수 있습니다. 그러나 큰 목록에서 많은 숫자를 확인하십시오 ...
테스트 :
from timeit import timeit
methods = ['''tocheck = [1,2] # items to check
a = [2,3,4] # the list
a = set(a) # convert to set (O(n))
[i for i in tocheck if i in a] # check items (O(m))''',
'''L1 = [2,3,4]
L2 = [1,2]
[i for i in L1 if i in L2]''',
'''S1 = set([2,3,4])
S2 = set([1,2])
S1.intersection(S2)''',
'''a = [1,2]
b = [2,3,4]
any(x in a for x in b)''']
for method in methods:
print timeit(method, number=10000)
print
methods = ['''tocheck = range(200,300) # items to check
a = range(2, 10000) # the list
a = set(a) # convert to set (O(n))
[i for i in tocheck if i in a] # check items (O(m))''',
'''L1 = range(2, 10000)
L2 = range(200,300)
[i for i in L1 if i in L2]''',
'''S1 = set(range(2, 10000))
S2 = set(range(200,300))
S1.intersection(S2)''',
'''a = range(200,300)
b = range(2, 10000)
any(x in a for x in b)''']
for method in methods:
print timeit(method, number=1000)
속도 :
M1: 0.0170331001282 # make one set
M2: 0.0164539813995 # list comprehension
M3: 0.0286040306091 # set intersection
M4: 0.0305438041687 # any
M1: 0.49850320816 # make one set
M2: 25.2735087872 # list comprehension
M3: 0.466138124466 # set intersection
M4: 0.668627977371 # any
지속적으로 빠른 방법은 (목록의) 하나의 세트를 만드는 것입니다.
경우에 따라 (예 : 고유 목록 요소) 설정 작업을 사용할 수 있습니다.
>>> a=[2,3,4]
>>> set(a) - set([2,3]) != set(a)
True
>>>
또는 사용 ) (set.isdisjoint를 ,
>>> not set(a).isdisjoint(set([2,3]))
True
>>> not set(a).isdisjoint(set([5,6]))
False
>>>
이것은 한 줄로 할 것입니다.
>>> a=[2,3,4]
>>> b=[1,2]
>>> bool(sum(map(lambda x: x in b, a)))
True
다른 답변과 의견에 언급 된 여러 솔루션을 수집 한 다음 속도 테스트를 실행했습니다. not set(a).isdisjoint(b)
가장 빠르다는 결과가 나왔을 때 속도가 느려지지 않았습니다 False
.
세 개의 실행 각각의 가능한 구성의 작은 샘플 테스트 a
와 b
. 시간은 마이크로 초입니다.
Any with generator and max
2.093 1.997 7.879
Any with generator
0.907 0.692 2.337
Any with list
1.294 1.452 2.137
True in list
1.219 1.348 2.148
Set with &
1.364 1.749 1.412
Set intersection explcit set(b)
1.424 1.787 1.517
Set intersection implicit set(b)
0.964 1.298 0.976
Set isdisjoint explicit set(b)
1.062 1.094 1.241
Set isdisjoint implicit set(b)
0.622 0.621 0.753
import timeit
def printtimes(t):
print '{:.3f}'.format(t/10.0),
setup1 = 'a = range(10); b = range(9,15)'
setup2 = 'a = range(10); b = range(10)'
setup3 = 'a = range(10); b = range(10,20)'
print 'Any with generator and max\n\t',
printtimes(timeit.Timer('any(x in max(a,b,key=len) for x in min(b,a,key=len))',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('any(x in max(a,b,key=len) for x in min(b,a,key=len))',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('any(x in max(a,b,key=len) for x in min(b,a,key=len))',setup=setup3).timeit(10000000))
print
print 'Any with generator\n\t',
printtimes(timeit.Timer('any(i in a for i in b)',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('any(i in a for i in b)',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('any(i in a for i in b)',setup=setup3).timeit(10000000))
print
print 'Any with list\n\t',
printtimes(timeit.Timer('any([i in a for i in b])',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('any([i in a for i in b])',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('any([i in a for i in b])',setup=setup3).timeit(10000000))
print
print 'True in list\n\t',
printtimes(timeit.Timer('True in [i in a for i in b]',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('True in [i in a for i in b]',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('True in [i in a for i in b]',setup=setup3).timeit(10000000))
print
print 'Set with &\n\t',
printtimes(timeit.Timer('bool(set(a) & set(b))',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('bool(set(a) & set(b))',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('bool(set(a) & set(b))',setup=setup3).timeit(10000000))
print
print 'Set intersection explcit set(b)\n\t',
printtimes(timeit.Timer('bool(set(a).intersection(set(b)))',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('bool(set(a).intersection(set(b)))',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('bool(set(a).intersection(set(b)))',setup=setup3).timeit(10000000))
print
print 'Set intersection implicit set(b)\n\t',
printtimes(timeit.Timer('bool(set(a).intersection(b))',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('bool(set(a).intersection(b))',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('bool(set(a).intersection(b))',setup=setup3).timeit(10000000))
print
print 'Set isdisjoint explicit set(b)\n\t',
printtimes(timeit.Timer('not set(a).isdisjoint(set(b))',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('not set(a).isdisjoint(set(b))',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('not set(a).isdisjoint(set(b))',setup=setup3).timeit(10000000))
print
print 'Set isdisjoint implicit set(b)\n\t',
printtimes(timeit.Timer('not set(a).isdisjoint(b)',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('not set(a).isdisjoint(b)',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('not set(a).isdisjoint(b)',setup=setup3).timeit(10000000))
print
나는 나의 상황이 당신이 찾고있는 것이 아닐 수도 있지만, 그것은 당신의 생각에 대안을 제공 할 수 있다고 말해야합니다.
set () 및 any () 메서드를 모두 시도했지만 여전히 속도에 문제가 있습니다. 그래서 Raymond Hettinger는 파이썬의 모든 것이 사전이며 가능할 때마다 dict를 사용한다고 말했습니다. 그것이 제가 시도한 것입니다.
나는 int와 함께 defaultdict를 사용하여 부정적인 결과를 표시하고 첫 번째 목록의 항목을 두 번째 목록의 키로 사용했습니다 (defaultdict로 변환). dict로 즉시 조회 할 수 있기 때문에 해당 항목이 defaultdict에 있는지 즉시 알 수 있습니다. 두 번째 목록의 데이터 구조를 항상 변경할 수는 없지만 처음부터 할 수 있다면 훨씬 빠릅니다. list2 (큰 목록)를 defaultdict로 변환해야 할 수 있습니다. 여기서 key는 작은 목록에서 확인하려는 잠재적 값이며 값은 1 (적중) 또는 0 (적중 없음, 기본값)입니다.
from collections import defaultdict
already_indexed = defaultdict(int)
def check_exist(small_list, default_list):
for item in small_list:
if default_list[item] == 1:
return True
return False
if check_exist(small_list, already_indexed):
continue
else:
for x in small_list:
already_indexed[x] = 1
a = [1, 2] b = [3, 5, 2, 6, 8, 9] c = [3, 5, 6, 8, 1, 9] print( (1 and 2) in b ,(2 and 1) in b ,(1 and 2) in c ,(2 and 1) in c, sep='\n')
True False입니다 False True