목록에서 요소의 모든 항목을 찾는 방법은 무엇입니까?


377

index()목록에서 항목의 첫 항목 만 제공합니다. 목록의 모든 인덱스를 반환하는 깔끔한 트릭이 있습니까?


1
이 질문에 약간 혼란 스럽습니다. 다차원 목록의 모든 수준에서 항목을 재귀 적으로 검색 하시겠습니까, 아니면 목록의 최상위 수준에서만 항목을 검색 하시겠습니까?
앤더슨 그린

22
제 생각에는 정확하게 이것을 수행하는 목록 방법이 있어야합니다.
otocan

답변:


544

목록 이해를 사용할 수 있습니다.

indices = [i for i, x in enumerate(my_list) if x == "whatever"]

3
오래된 파이썬에서는 본질적으로 동일한 기능을 위해 filter ()를 사용하십시오.
Gleno

44
리스트 이해는 파이썬에서 2.0, enumerate2.3 에서 나타났습니다 . 예, 파이썬이 고대라면을 사용하십시오 filter().
Steven Rumbalski

2
이 기법은 다차원 배열에서 항목의 모든 항목을 찾지는 않습니다. 예를 들어 대신을 print([i for i, x in enumerate([[1,1],[0,1]]) if x == 1])반환 []합니다 [[0, 1], [0, 0], [1, 1]].
앤더슨 그린

9
@AndersonGreen : "다차원 배열"이라는 용어는 각 축을 따라 균일 한 크기를 보장하는 데이터 구조를 나타냅니다. 일반 파이썬에는 그러한 데이터 구조가 없습니다. 목록의 목록이 있지만 "다차원 배열"과는 매우 다릅니다. 후자를 원한다면 (a == 1).nonzero()NumPy 배열을 사용하는 것을 허용하는 NumPy 사용을 고려해야 a합니다.
Sven Marnach 2014

2
@MadmanLee 빠른 것을 원하면 NumPy를 사용하십시오.
Georgy

117

직접 목록에 대한 해결책은 아니지만 numpy실제로 이런 종류의 일이 빛납니다.

import numpy as np
values = np.array([1,2,3,1,2,4,5,6,3,2,1])
searchval = 3
ii = np.where(values == searchval)[0]

보고:

ii ==>array([2, 8])

이것은 다른 솔루션에 비해 많은 수의 요소가있는 목록 (배열)의 경우 훨씬 빠릅니다.


2
끝에 [0]이 배열이 될 문자열을 문자열로 변환하는 것을 알았습니다. 왜 당신이 이것을 선택했는지 궁금합니다.
amelia

5
@amelia [0]은 필요 where합니다. 튜플을 반환하기 때문입니다(array([2, 8], dtype=int64),)
Winand

1
안녕하세요 @Winand [0]에 넣었지만 여전히 두 부분을 모두 얻습니다. 내 코드는 다음과 같습니다. (nrg.local_logs.all_id_resp_address는 목록입니다) "ste ="199.38.164.165 "value = np.where (nrg.local_logs.all_id_resp_address == ste) [0]"말할 수 있으면 기쁠 것입니다 내가 잘못한 것
Tomer

2
@Tomer는 우선해서 all_id_resp_addressnp.array안됩니다 list.
Winand

1
당신이 비교하려고 @Tomer list하고 str, 분명 당신은 전달 Falsenp.where. 당신 np.array이 smth와 비교할 때 . 부울 값의 배열을 얻습니다. 그런 다음 해당 배열 np.where의 모든 True값 위치를 찾습니다 .
Winand

29

다음을 사용하는 솔루션 list.index:

def indices(lst, element):
    result = []
    offset = -1
    while True:
        try:
            offset = lst.index(element, offset+1)
        except ValueError:
            return result
        result.append(offset)

enumerate큰 목록의 경우 목록 이해력보다 훨씬 빠릅니다 . 이미 배열이있는 경우numpy 솔루션 보다 속도가 느립니다 . 그렇지 않으면 변환 비용이 속도 게인 보다 높습니다 (100, 1000 및 10000 요소가있는 정수 목록에서 테스트 됨).

노트: Chris_Rands의 의견에 근거한주의 사항 :이 솔루션은 결과가 충분히 희소하지만 목록에 검색되는 요소의 인스턴스가 많은 경우 (목록의 ~ 15 % 이상) 목록 이해보다 빠릅니다. , 1000 개의 정수 목록이있는 테스트에서) 목록 이해가 더 빠릅니다.


3
이것이 목록 광고보다 빠르다고 말하면 이것을 보여주는 타이밍을 보여줄 수 있습니까?
Chris_Rands

4
이것은 오래 전에 timeit.timeit무작위로 생성 된 목록과 함께 사용되었을 것입니다 . 그것은 중요한 점이지만, 그것이 당신이 묻는 이유 일 것입니다. 당시에는 그것이 발생하지 않았지만 결과가 충분히 희박한 경우에만 속도 증가가 사실입니다. 방금 검색 할 요소로 가득 찬 목록으로 테스트했으며 목록 이해보다 훨씬 느립니다.
Paulo Almeida

18

어때요 :

In [1]: l=[1,2,3,4,3,2,5,6,7]

In [2]: [i for i,val in enumerate(l) if val==3]
Out[2]: [2, 4]

10
occurrences = lambda s, lst: (i for i,e in enumerate(lst) if e == s)
list(occurrences(1, [1,2,3,1])) # = [0, 3]

8

more_itertools.locate 조건을 만족하는 모든 항목에 대한 인덱스를 찾습니다.

from more_itertools import locate


list(locate([0, 1, 1, 0, 1, 0, 0]))
# [1, 2, 4]

list(locate(['a', 'b', 'c', 'b'], lambda x: x == 'b'))
# [1, 3]

more_itertools타사 라이브러리 > pip install more_itertools입니다.


1
이 lib가 conda-forge에 추가되면 좋을 것입니다 ( conda install최근 성능이 매우 불안정 해졌 지만 )
matanster

4

모든 경우에 대한 하나 이상의 솔루션 (중복 된 경우 죄송합니다) :

values = [1,2,3,1,2,4,5,6,3,2,1]
map(lambda val: (val, [i for i in xrange(len(values)) if values[i] == val]), values)

4

또는 사용 range(파이썬 3) :

l=[i for i in range(len(lst)) if lst[i]=='something...']

(파이썬 2)의 경우 :

l=[i for i in xrange(len(lst)) if lst[i]=='something...']

그리고 (두 경우 모두) :

print(l)

예상대로입니다.


4

python2에서 filter () 사용.

>>> q = ['Yeehaw', 'Yeehaw', 'Googol', 'B9', 'Googol', 'NSM', 'B9', 'NSM', 'Dont Ask', 'Googol']
>>> filter(lambda i: q[i]=="Googol", range(len(q)))
[2, 4, 9]

2

당신은 defaultdict를 만들 수 있습니다

from collections import defaultdict
d1 = defaultdict(int)      # defaults to 0 values for keys
unq = set(lst1)              # lst1 = [1, 2, 2, 3, 4, 1, 2, 7]
for each in unq:
      d1[each] = lst1.count(each)
else:
      print(d1)

2

모든 발생 및 목록에서 하나 이상의 (동일한) 항목 위치 가져 오기

enumerate (alist)를 사용하면 요소 x가 찾는 것과 같을 때 목록의 인덱스 인 첫 번째 요소 (n)를 저장할 수 있습니다.

>>> alist = ['foo', 'spam', 'egg', 'foo']
>>> foo_indexes = [n for n,x in enumerate(alist) if x=='foo']
>>> foo_indexes
[0, 3]
>>>

findindex 함수를 만들어 봅시다

이 함수는 항목과 목록을 인수로 사용하여 이전에 본 것처럼 목록에서 항목의 위치를 ​​반환합니다.

def indexlist(item2find, list_or_string):
  "Returns all indexes of an item in a list or a string"
  return [n for n,item in enumerate(list_or_string) if item==item2find]

print(indexlist("1", "010101010"))

산출


[1, 3, 5, 7]

단순한

for n, i in enumerate([1, 2, 3, 4, 1]):
    if i == 1:
        print(n)

산출:

0
4

이 답변은 기존 코드에서 가장 쉽게 구현할 수있었습니다.
Ryan Harris

2

사용하여 for-loop:

  • 답변 enumerate목록 이해 보다 효율적이고 파이썬, 그러나,이 답변은 그 중 일부를 사용 할 수 없습니다 학생들을 대상으로 내장 된 기능을 .
  • 빈 목록을 만들고 indices
  • 와 루프를 만들 for i in range(len(x)): 기본적으로 인덱스 위치 목록을 반복합니다.[0, 1, 2, 3, ..., len(x)-1]
  • 루프에서에 일치하는 i곳 을x[i]valueindices
def get_indices(x: list, value: int) -> list:
    indices = list()
    for i in range(len(x)):
        if x[i] == value:
            indices.append(i)
    return indices

n = [1, 2, 3, -50, -60, 0, 6, 9, -60, -60]
print(get_indices(n, -60))

>>> [4, 8, 9]
  • 함수 get_indicestype hints 로 구현됩니다 . 이 경우, 목록에서 n의 무리입니다 int들, 그러므로 우리는 검색 value도 정의,int .

사용 while-loop.index:

  • .index사용 try-except에 대한 오류 처리 a는 때문에 ValueError경우에 발생합니다 value목록에 없습니다.
def get_indices(x: list, value: int) -> list:
    indices = list()
    i = 0
    while True:
        try:
            # find an occurrence of value and update i to that index
            i = x.index(value, i)
            # add i to the list
            indices.append(i)
            # advance i by 1
            i += 1
        except ValueError as e:
            break
    return indices

print(get_indices(n, -60))
>>> [4, 8, 9]

자체 정의 get_indeices는 일반 목록 이해보다 약간 빠릅니다 (~ 15 %). 나는 그것을 알아 내려고 노력하고있다.
트래비스

1

Python 2를 사용하는 경우 다음과 동일한 기능을 수행 할 수 있습니다.

f = lambda my_list, value:filter(lambda x: my_list[x] == value, range(len(my_list)))

my_list색인을 가져 오려는 목록은 어디에 있고 value검색된 값입니다. 용법:

f(some_list, some_element)

1

특정 색인 사이의 모든 요소 위치를 검색해야하는 경우 다음을 지정할 수 있습니다.

[i for i,x in enumerate([1,2,3,2]) if x==2 & 2<= i <=3] # -> [3]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.