파이썬

[Python] 목록에서 항목의 인덱스 찾기

zooheon 2022. 7. 31. 14:05
반응형

["foo", "bar", "baz"]목록 과 목록의 항목이 주어지면 "bar"색인을 어떻게 얻 1습니까?

 

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

참조: 데이터 구조 > 목록에 대한 추가 정보

주의 사항은 다음과 같습니다.

이것이 아마도 질문에 대답하는 가장 깨끗한 방법 수 있지만 API index의 다소 약한 구성 요소이며 list화가 나서 마지막으로 사용한 시간이 기억나지 않습니다. 이 답변은 많이 참조되기 때문에 더 완전해야 한다는 의견에서 나에게 지적되었습니다. 팔로우 에 대한 몇 가지 주의 사항 list.index. 처음에는 이에 대한 문서를 살펴보는 것이 좋습니다.

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

값이 x 와 같은 첫 번째 항목의 목록에서 0부터 시작하는 인덱스를 반환합니다 . ValueError그런 항목이 없으면 올립니다 .

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

목록 길이의 선형 시간 복잡도

index호출은 일치하는 항목을 찾을 때까지 목록의 모든 요소를 ​​순서대로 확인합니다 . 목록이 길고 목록의 어디에서 발생하는지 대략 모르는 경우 이 검색이 병목 현상이 될 수 있습니다. 이 경우 다른 데이터 구조를 고려해야 합니다. 일치하는 항목을 찾을 위치를 대략적으로 알고 있으면 index힌트를 줄 수 있습니다. 예를 들어, 이 스니펫에서 직선 은 10개 항목만 검색하면 되지만 후자는 백만 개를 검색하기 때문에 l.index(999_999, 999_990, 1_000_000)직선보다 약 5배 더 빠릅니다 .l.index(999_999)

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

인수 에 대한 첫 번째 일치 항목 의 인덱스만 반환합니다.

에 대한 호출 index은 일치하는 항목을 찾을 때까지 목록을 순서대로 검색하고 거기서 멈춥니다. 일치하는 인덱스가 더 필요할 것으로 예상되는 경우 목록 이해 또는 생성기 표현식을 사용해야 합니다.

>>> [1, 1].index(1)
0
>>> [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)
>>> next(g)
0
>>> next(g)
2

내가 한때 사용했을 대부분의 장소에서 index이제는 목록 이해 또는 생성기 표현식을 사용합니다. 왜냐하면 그것들이 더 일반화 가능하기 때문입니다. 따라서 에 도달하는 것을 고려하고 있다면 index이러한 뛰어난 Python 기능을 살펴보십시오.

요소가 목록에 없으면 throw

항목이 없는 경우 에 대한 호출이 index발생 합니다.ValueError

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

항목이 목록에 없으면 다음 중 하나를 수행해야 합니다.

  1. item in my_list(깨끗하고 읽기 쉬운 접근 방식)으로 먼저 확인 하거나
  2. 포착 index하는 블록으로 호출을 래핑합니다 (적어도 검색할 목록이 길고 항목이 일반적으로 존재할 때 더 빠를 것입니다.)try/exceptValueError

 

Python 학습에 정말 도움이 되는 한 가지는 대화형 도움말 기능을 사용하는 것입니다.

>>> help(["foo", "bar", "baz"])
Help on list object:

class list(object)
 ...

 |
 |  index(...)
 |      L.index(value, [start, [stop]]) -> integer -- return first index of value
 |

이것은 종종 당신이 찾고 있는 방법으로 당신을 이끌 것입니다.

 

대부분의 답변 은 단일 인덱스 를 찾는 방법을 설명 하지만 항목이 목록에 여러 번 있는 경우 해당 메서드는 여러 인덱스를 반환하지 않습니다. 사용 enumerate():

for i, j in enumerate(['foo', 'bar', 'baz']):
    if j == 'bar':
        print(i)

index()함수는 첫 번째 항목만 반환하고 enumerate()모든 항목을 반환합니다.

목록 이해:

[i for i, j in enumerate(['foo', 'bar', 'baz']) if j == 'bar']

itertools.count()다음 은 열거하는 것과 거의 동일한 접근 방식을 사용하는 또 다른 작은 솔루션입니다 .

from itertools import izip as zip, count # izip for maximum efficiency
[i for i, j in zip(count(), ['foo', 'bar', 'baz']) if j == 'bar']

이것은 다음을 사용하는 것보다 큰 목록에 더 효율적입니다 enumerate().

$ python -m timeit -s "from itertools import izip as zip, count" "[i for i, j in zip(count(), ['foo', 'bar', 'baz']*500) if j == 'bar']"
10000 loops, best of 3: 174 usec per loop
$ python -m timeit "[i for i, j in enumerate(['foo', 'bar', 'baz']*500) if j == 'bar']"
10000 loops, best of 3: 196 usec per loop

 

반응형