Как найти все вхождения элемента в списке? - PullRequest
289 голосов
/ 09 июня 2011

index() просто выдаст первое вхождение элемента в списке. Есть ли хитрый трюк, который возвращает все индексы в списке?

Ответы [ 14 ]

422 голосов
/ 09 июня 2011

Вы можете использовать понимание списка:

indices = [i for i, x in enumerate(my_list) if x == "whatever"]
95 голосов
/ 09 июня 2011

Хотя это не решение для списков напрямую, 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])

Это может быть значительно быстрее для списков (массивов) с большим количеством элементов по сравнению с некоторыми другими решениями.

28 голосов
/ 07 сентября 2013

Решение с использованием 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 целых чисел), понимание списка быстрее.

16 голосов
/ 09 июня 2011

Как насчет:

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]
7 голосов
/ 09 июня 2011
occurrences = lambda s, lst: (i for i,e in enumerate(lst) if e == s)
list(occurrences(1, [1,2,3,1])) # = [0, 3]
5 голосов
/ 09 февраля 2018

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.

4 голосов
/ 03 апреля 2019

Использование фильтра () в python2.

>>> q = ['Yeehaw', 'Yeehaw', 'Googol', 'B9', 'Googol', 'NSM', 'B9', 'NSM', 'Dont Ask', 'Googol']
>>> filter(lambda i: q[i]=="Googol", range(len(q)))
[2, 4, 9]
4 голосов
/ 09 июня 2011

Еще одно решение (извините, если дублирует) для всех случаев:

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)
3 голосов
/ 18 октября 2018

Или используйте range (python 3):

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

Для (Python 2):

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

А потом (оба случая):

print(l)

Как и ожидалось.

2 голосов
/ 07 декабря 2017

Вы можете создать 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...