[python] 파이썬의 목록에없는 것이 있는지 확인하십시오.

파이썬 에 튜플 목록이 있고 튜플이 목록에없는 경우에만 지점을 가져 가고 싶은 조건부가 있습니다 (목록에있는 경우 if 분기를 사용하고 싶지 않습니다)

if curr_x -1 > 0 and (curr_x-1 , curr_y) not in myList: 

    # Do Something

이것은 실제로 나를 위해 작동하지 않습니다. 내가 뭘 잘못 했니?



답변

버그는 아마도 코드의 다른 곳에있을 것입니다.

>>> 3 not in [2, 3, 4]
False
>>> 3 not in [4, 5, 6]
True

또는 튜플로 :

>>> (2, 3) not in [(2, 3), (5, 6), (9, 1)]
False
>>> (2, 3) not in [(2, 7), (7, 3), "hi"]
True


답변

파이썬의 목록에 무언가가 없는지 어떻게 확인합니까?

가장 저렴하고 읽기 쉬운 솔루션은 in연산자 (또는 특정 경우 not in)를 사용하는 것입니다. 설명서에서 언급했듯이

운영자 innot in회원 자격 테스트 x in s로 평가
True하는 경우 x의 구성원 s, 그리고 False그렇지. x not in s의 부정을 반환합니다 x in s.

또한

연산자 not in는의 참 값을 갖도록 정의됩니다 in.

y not in x논리적으로와 같습니다 not y in x.

다음은 몇 가지 예입니다.

'a' in [1, 2, 3]
# False

'c' in ['a', 'b', 'c']
# True

'a' not in [1, 2, 3]
# True

'c' not in ['a', 'b', 'c']
# False

튜플은 해시 가능하기 때문에 튜플과 함께 작동합니다 (튜플도 불변이기 때문에).

(1, 2) in [(3, 4), (1, 2)]
#  True

RHS의 객체가 __contains__()메소드를 정의하는 경우 문서 비교 섹션의 in마지막 단락에 언급 된대로 내부적 으로 메소드를 호출합니다 .

innot in, 반복 가능한이다 또는 구현 유형을 지원하는
__contains__()방법을. 예를 들어, 당신은 이것을 할 수 있지만 그렇게해서는 안됩니다 :

[3, 2, 1].__contains__(1)
# True

in단락이 있으므로 요소가 목록의 시작 부분에 있으면 in더 빨리 평가됩니다.

lst = list(range(10001))
%timeit 1 in lst
%timeit 10000 in lst  # Expected to take longer time.

68.9 ns ± 0.613 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
178 µs ± 5.01 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

항목이 목록에 있는지 확인하는 것 이상을 수행하려면 옵션이 있습니다.

  • list.index항목의 색인을 검색하는 데 사용할 수 있습니다. 해당 요소가 없으면 a ValueError가 발생합니다.
  • list.count 발생 횟수를 계산하려는 경우 사용할 수 있습니다.

XY 문제 : 당신은 sets 를 고려 했습니까 ?

다음과 같은 질문을 해보십시오.

  • 항목이 목록에 두 번 이상 있는지 확인해야합니까?
  • 이 검사는 루프 또는 반복적으로 호출되는 함수 내에서 수행됩니까?
  • 목록에 저장 한 항목이 해시 가능합니까? IOW, 당신 hash은 그들 에게 전화 할 수 있습니까?

이 질문에 “예”라고 대답 한 경우 set대신 사용하십시오 . 의 in멤버쉽 테스트 list는 O (n) 시간 복잡성입니다. 이것은 파이썬이 목록의 선형 스캔을 수행하여 각 요소를 방문하고 검색 항목과 비교해야한다는 것을 의미합니다. 이 작업을 반복적으로 수행하거나 목록이 크면이 작업에 오버 헤드가 발생합니다.

set반면에 객체는 일정한 시간 멤버쉽 확인을 위해 값을 해시합니다. 확인은 다음을 사용하여 수행됩니다 in.

1 in {1, 2, 3} 
# True

'a' not in {'a', 'b', 'c'}
# False

(1, 2) in {('a', 'c'), (1, 2)}
# True

불행히도 검색 / 검색하지 않는 요소가 목록의 끝에있을 때 파이썬은 목록을 끝까지 스캔합니다. 이것은 아래의 타이밍에서 분명합니다.

l = list(range(100001))
s = set(l)

%timeit 100000 in l
%timeit 100000 in s

2.58 ms ± 58.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
101 ns ± 9.53 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

기억하고, 이것은 저장하고 조회하는 요소가 해시 가능한 한 적합한 옵션입니다. IOW는 불변 유형이거나 구현하는 객체 여야합니다 __hash__.


답변