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


314

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

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

    # Do Something

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


1
참고는 3 -1 > 0 and (4-1 , 5) not in []⤇ True따라서 오류 운영자 우선 아니다.
— Dan D.

6
"정말 나를 위해 일하지 않는다"는 것은 무엇을 의미합니까? 당신은 어떻게 될 것으로 예상합니까? 실제로 어떻게됩니까? 어떤 정확한 목록 내용이 문제를 유발합니까?
— Karl Knechtel 1

왜 시도하지 myList.count((curr_x, curr_y))경우 (curr_x, curr_y)에없는 myList결과가 될 것입니다0
— LittleLittleQ


2
이 "내 코드가 실제로 작동하지 않습니다"라는 질문에 297 번의 공감대가 어떻게 나타 났습니까? 최소한의 재현 가능한 예를 제시하십시오 .
— gerrit

답변:


502

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

>>> 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

11
@Zack : 당신이 이것에 대해 몰랐다면, 당신은 그냥 할 수 있습니다if not ELEMENT in COLLECTION:
— ninjagecko

@ninjagecko : 덜 효율적이거나 부정확 할 수있는 컨테이너 유형에 따라 다릅니다. 블룸 필터를 참조하십시오 .
— orlp

14
@nightcracker 즉, 어떠한 의미하지 않습니다 A not in B일에 감소 not B.__contains__(A)하는 것은 무엇과 동일 not A in B하다로 감소된다 not B.__contains__(A).
— Dan D.

1
와우, 나는 파이썬이 같은 것을 맹세 할 수 있었다 __notcontains__. 미안하지만 내가 한 말은 헛소리 야
— orlp

2
@ std''OrgnlDave 발생할 수있는 유일한 방법은 그렇지 않은 not것보다 우선 순위가 높은 경우 in입니다. 의 결과 고려 ast.dump(ast.parse("not A in B").body[0])의 결과를하는 "Expr(value=UnaryOp(op=Not(), operand=Compare(left=Name(id='A', ctx=Load()), ops=[In()], comparators=[Name(id='B', ctx=Load())])))"경우는 notA를 단단히 그룹화를 한 것으로 결과를 예상 한 것 "Expr(value=Compare(left=UnaryOp(op=Not(), operand=Name(id='A', ctx=Load())), ops=[In()], comparators=[Name(id='B', ctx=Load())]))"에 대한 해석이다 "(not A) in B".
— Dan D.

20

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

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

운영자 in및 not 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마지막 단락에 언급 된대로 내부적 으로 메소드를 호출합니다 .

... in와 not 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__.


2
세트는 항상 옵션이 아닙니다 (예 : 변경 가능한 항목 목록이있는 경우). 대규모 콜렉션의 경우 : 조회 세트를 작성하는 것은 어쨌든 O (n) 시간이며 메모리 사용량을 두 배로 늘릴 수 있습니다. 아직 검색하지 않은 경우 항상 검색 / 유지 관리하는 것이 최선의 선택은 아닙니다.
— wim
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.