Найдите место всех одинаковых объектов в списке [duplicate]

Обязательно установите

 $.validator.setDefaults({ ignore: '' });

НЕ внутри $(document).ready

243
задан Lafexlos 24 March 2016 в 15:41
поделиться

12 ответов

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

indices = [i for i, x in enumerate(my_list) if x == "whatever"]
333
ответ дан Sven Marnach 16 August 2018 в 08:07
поделиться
  • 1
    На старых питонах используйте filter () для практически одинаковой функциональности. – Gleno 9 June 2011 в 15:30
  • 2
    Перечисления списков отображаются в python на 2.0, enumerate в 2.3. Итак, да, если ваш Python древний, используйте filter(). – Steven Rumbalski 9 June 2011 в 15:36
  • 3
    Этот метод не найдет все вхождения элемента в многомерном массиве. Например, print([i for i, x in enumerate([[1,1],[0,1]]) if x == 1]) возвращает [] вместо [[0, 1], [0, 0], [1, 1]]. – Anderson Green 3 February 2014 в 22:33
  • 4
    @AndersonGreen: Термин "многомерный массив" предлагает структуру данных, которая гарантированно имеет одинаковый размер вдоль каждой из ее осей. Нет такой структуры данных в простом Python. Есть списки списков, но они сильно отличаются от «многомерных массивов». Если вы хотите использовать последнее, вам следует использовать NumPy, который позволяет вам делать такие вещи, как (a == 1).nonzero() для массива NumPy a. – Sven Marnach 4 February 2014 в 16:10
  • 5
    @AndersonGreen Это не то, о чем попросил OP ... – scornwell 23 October 2014 в 23:36

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

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
ответ дан Artsiom Rudzenka 16 August 2018 в 08:07
поделиться

Если вам нужно искать позиции всех элементов между определенными индексами , вы можете указать их:

[i for i,x in enumerate([1,2,3,2]) if x==2 & 2<= i <=3] # -> [3]
0
ответ дан Denis Rasulev 16 August 2018 в 08:07
поделиться

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

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

76
ответ дан JoshAdel 16 August 2018 в 08:07
поделиться
  • 1
    Я заметил, что [0] в конце преобразует то, что будет массивом в строку. Мне любопытно, почему вы решили это сделать. – amelia 13 June 2016 в 16:11
  • 2
    @amelia [0] необходимо, потому что where возвращает кортеж (array([2, 8], dtype=int64),) – Winand 5 August 2016 в 10:27
  • 3
    Привет @Winand, я положил [0], но все равно получаю обе части. Вот мой код: (nrg.local_logs.all_id_resp_address - это список) & quot; ste = "199.38.164.165 & quot; value = np.where (nrg.local_logs.all_id_resp_address == ste) [0] & quot; Я буду рад, если вы скажете мне, что я сделал неправильно – Tomer 15 August 2016 в 05:05
  • 4
    @Tomer прежде всего all_id_resp_address должен быть np.array не list. – Winand 15 August 2016 в 05:15
  • 5
    @Tomer вы пытались сравнить list и str, очевидно, что вы передали False в np.where. Когда вы сравниваете np.array с чем-л. вы получаете массив логических значений. Затем np.where находит позиции всех значений True этого массива. – Winand 15 August 2016 в 06:45

Если вы используете 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)
0
ответ дан Mr. Xcoder 16 August 2018 в 08:07
поделиться

Как насчет:

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]
12
ответ дан NPE 16 August 2018 в 08:07
поделиться

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

24
ответ дан Paulo Almeida 16 August 2018 в 08:07
поделиться
  • 1
    Вы говорите, что это быстрее, чем список comp, можете ли вы показать свои тайминги, демонстрирующие это? – Chris_Rands 9 November 2017 в 14:09
  • 2
    Это было давно, я, вероятно, использовал timeit.timeit со случайно сгенерированными списками. Но это важный момент, и я полагаю, что это может быть поэтому и спросить. В то время это мне не приходило в голову, но прирост скорости верен только в том случае, если результаты достаточно разрежены. Я просто протестировал список, полный элемента для поиска, и он намного медленнее, чем понимание списка. – Paulo Almeida 9 November 2017 в 15:58
occurrences = lambda s, lst: (i for i,e in enumerate(lst) if e == s)
list(occurrences(1, [1,2,3,1])) # = [0, 3]
5
ответ дан phihag 16 August 2018 в 08:07
поделиться

Вы можете создать 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)
0
ответ дан privatevoid 16 August 2018 в 08:07
поделиться

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.

2
ответ дан pylang 16 August 2018 в 08:07
поделиться

Редактировать (Idiotness):

Добавление к хорошим ответам.

def count(x, lst):
    ind = []
    for i in lst:
        if i == x:
            ind.append(lst.index(x))
    return ind
-3
ответ дан Trufa 16 August 2018 в 08:07
поделиться
  • 1
    Действительно ли это возвращает индексы всех элементов lst == x? – JoshAdel 9 June 2011 в 15:54
  • 2
    @JoshAdel: Извините! спасибо за головы, я неправильно понял вопрос, я отредактировал. – Trufa 9 June 2011 в 16:05
  • 3
    Он не возвращает индексы всех элементов из lst == x. – Yaroslav Admin 4 September 2015 в 11:49
  • 4
    Он всегда возвращает первый индекс – sri85 12 June 2016 в 17:14
  • 5
    @Trufa, почему бы просто не удалить этот ответ? – Matthew Purdon 27 June 2017 в 01:07
0
ответ дан U9-Forward 29 October 2018 в 11:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: