본문 바로가기
Python/Python FAQ

Python 리스트에서 항목의 인덱스를 찾는 방법, Finding the index of an item in a list

by 베타코드 2023. 5. 4.
반응형

질문


리스트 ["foo", "bar", "baz"]와 리스트 내 항목 "bar"가 주어졌을 때, 해당 항목의 인덱스 1을 어떻게 얻을 수 있을까요?


답변


>>> ["foo", "bar", "baz"].index("bar")
1

내장된 .index() 메소드의 문서를 참조하십시오:

list.index(x[, start[, end]])

값이 x와 같은 첫 번째 항목의 0을 기준으로 한 리스트 내의 인덱스를 반환합니다. 해당 항목이 없으면 ValueError가 발생합니다.

선택적 인수 startend슬라이스 표기법과 같이 해석되며 리스트의 특정 하위 시퀀스에서 검색을 제한하는 데 사용됩니다. 반환된 인덱스는 시작 인수가 아닌 전체 시퀀스의 시작부터 계산됩니다.

주의 사항

리스트 길이에 대한 선형 시간 복잡성

index 호출은 일치하는 항목을 찾을 때까지 순서대로 리스트의 모든 요소를 확인합니다. 리스트가 길고 값이 시작 부근에 있을 것이 보장되지 않으면 이는 코드를 느리게 만들 수 있습니다.

이 문제는 다른 데이터 구조를 사용해야만 완전히 피할 수 있습니다. 그러나 요소가 리스트의 특정 부분에 있을 것으로 알려져 있다면, startend 매개변수를 사용하여 검색 범위를 좁힐 수 있습니다.

예를 들어:

>>> import timeit
>>> timeit.timeit('l.index(999_999)', setup='l = list(range(0, 1_000_000))', number=1000)
9.356267921015387
>>> timeit.timeit('l.index(999_999, 999_990, 1_000_000)', setup='l = list(range(0, 1_000_000))', number=1000)
0.0004404920036904514

두 번째 호출은 1백만 개의 모든 요소를 검색하는 대신 10개의 요소만 검색하면 되므로 몇 가지 차이가 있습니다.

첫 번째 일치 항목의 인덱스만 반환됩니다.

index 호출은 일치하는 항목을 찾을 때까지 리스트를 순서대로 검색하고 그곳에서 멈춥니다. 값이 두 번 이상 나타날 수 있고 모든 인덱스가 필요한 경우, index는 문제를 해결할 수 없습니다:

>>> [1, 1].index(1) # `1`의 인덱스가 발견되지 않습니다.
0

대신 리스트 컴프리헨션 또는 제너레이터 표현식을 사용하여 검색하고, enumerate를 사용하여 인덱스를 가져와야 합니다::

>>> # 리스트 컴프리헨션은 인덱스 목록을 직접 제공합니다:
>>> [i for i, e in enumerate([1, 2, 1]) if e == 1]
[0, 2]
>>> # 제너레이터 컴프리헨션은 반복 가능한 객체를 제공합니다...
>>> g = (i for i, e in enumerate([1, 2, 1]) if e == 1)
>>> # `for` 루프에서 사용하거나 `next`로 수동으로 반복할 수 있습니다:
>>> next(g)
0
>>> next(g)
2

리스트 컴프리헨션 및 제너레이터 표현식 기술은 하나의 일치 항목만 있는 경우에도 작동하며, 더 일반적입니다.

일치하는 항목이 없으면 예외가 발생합니다.

위의 문서에서 언급한 대로, .index를 사용하면 검색 대상 값이 리스트에 없으면 예외가 발생합니다:

>>> [1, 1].index(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 2 is not in list

이것이 문제가 될 경우, item in my_list를 사용하여 명시적으로 먼저 확인하거나 적절한 경우 try/except로 예외를 처리하십시오.

명시적 확인은 간단하고 읽기 쉬우나 두 번째로 목록을 반복해야 합니다. 이 선택에 대한 더 많은 지침은 파이썬의 EAFP 원칙을 참조하십시오.

반응형

댓글