programing

다음 항목 중 하나가 목록에 있는지 확인하는 방법은 무엇입니까?

sourcetip 2023. 1. 20. 17:40
반응형

다음 항목 중 하나가 목록에 있는지 확인하는 방법은 무엇입니까?

아래 항목 중 하나가 목록에 있는지 확인하기 위해 간단한 방법을 찾고 있지만, 첫 번째 시도가 작동하지 않습니다.이를 위해 함수를 작성하는 것 외에 여러 항목 중 하나가 목록에 있는지 확인하는 간단한 방법이 있습니다.

>>> a = [2,3,4]
>>> print (1 or 2) in a
False
>>> print (2 or 1) in a
True
>>> 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이므로 값을 True 값으로 직접 사용할 수 있습니다.

아, 토바이어스가 나보다 먼저 했구나귀사의 솔루션에 대해 다음과 같은 약간의 변화를 생각하고 있습니다.

>>> a = [1,2,3,4]
>>> b = [2,7]
>>> any(x in a for x in b)
True

좀 더 게을러질 수도 있어요.

a = [1,2,3,4]
b = [2,7]

print any((True for x in a if x in b))

암호가 실제로 무엇을 의미하는지 생각해 보세요!

>>> (1 or 2)
1
>>> (2 or 1)
2

아마 설명이 될 것이다. :) Python은 분명히 "lazy or"를 구현하고 있는데, 이는 놀랄 일이 아니다.다음과 같이 동작합니다.

def or(x, y):
    if x: return x
    if y: return y
    return False

번째 예에서는 " " 입니다.x == 1 ★★★★★★★★★★★★★★★★★」y == 2두 번째 예에서는 그 반대입니다.그렇기 때문에 순서에 따라 다른 값을 반환합니다.

a = {2,3,4}
if {1,2} & a:
    pass

코드 골프 버전그렇게 하는 것이 타당하다면 세트를 사용하는 것을 고려해 보십시오.나는 이것이 목록 이해보다 더 읽기 쉽다고 생각한다.

목록 합산 없이 한 줄.

>>> any(map(lambda each: each in [2,3,4], [1,2]))
True
>>> any(map(lambda each: each in [2,3,4], [1,5]))
False
>>> any(map(lambda each: each in [2,3,4], [2,4]))
True

내가 할 수 있는 최선의 방법:

any([True for e in (1, 2) if e in a])

python 3에서는 unpack asterisk를 사용할 수 있습니다.다음 두 가지 목록이 지정됩니다.

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.isdisconnect()사용하여

>>> not set(a).isdisjoint(set([2,3]))
True
>>> not set(a).isdisjoint(set([5,6]))
False
>>> 

다른 답변이나 코멘트에 기재되어 있는 몇개의 솔루션을 수집해, 속도 테스트를 실시했습니다. 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

이렇게 하면 한 줄로 할 수 있습니다.

>>> a=[2,3,4]
>>> b=[1,2]
>>> bool(sum(map(lambda x: x in b, a)))
True

제 상황은 당신이 원하는 것이 아닐 수도 있지만, 당신의 생각에 대한 대안이 될 수도 있습니다.

set() 메서드와 any() 메서드를 모두 시도했지만 속도에 문제가 있습니다.Raymond Hettinger가 python의 모든 것은 사전이고 언제든지 dict를 사용한다고 했던 것을 기억합니다.그래서 노력했어요.

부정적인 결과를 나타내기 위해 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

간단하죠.

_new_list = []
for item in a:
    if item in b:
        _new_list.append(item)
    else:
        pass

언급URL : https://stackoverflow.com/questions/740287/how-to-check-if-one-of-the-following-items-is-in-a-list

반응형