Hoe vind je alle exemplaren van een element in een lijst

index()geeft het eerste voorkomen van een item in een lijst. Is er een handige truc die alle indices in een lijst voor een element retourneert?


Antwoord 1, autoriteit 100%

U kunt een lijstbegrip gebruiken:

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

De iterator enumerate(my_list)levert paren (index, item)op voor elk item in de lijst. Door i, xals lusvariabel doel te gebruiken, worden deze paren uitgepakt in de index ien het lijstitem x. We filteren naar alle xdie aan ons criterium voldoen en selecteren de indices ivan deze elementen.


Antwoord 2, autoriteit 20%

Hoewel het geen directe oplossing is voor lijsten, blinkt numpyecht uit voor dit soort dingen:

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]

retourneert:

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

Dit kan aanzienlijk sneller zijn voor lijsten (arrays) met een groot aantal elementen versus sommige van de andere oplossingen.


Antwoord 3, autoriteit 5%

Een oplossing met behulp van 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)

Het is veel sneller dan het begrijpen van lijsten met enumerate, voor grote lijsten. Het is ook veel langzamer dan de numpy-oplossing alsje de array al hebt, anders wegen de kosten van het converteren op tegen de snelheidswinst (getest op integer-lijsten met 100, 1000 en 10000 elementen).

OPMERKING:een waarschuwing op basis van de opmerking van Chris_Rands: deze oplossing is sneller dan het begrip van de lijst als de resultaten voldoende schaars zijn, maar als de lijst veel instanties bevat van het element dat wordt gezocht (meer dan ~15% van de lijst, op een test met een lijst van 1000 gehele getallen), is het begrip van de lijst sneller.


Antwoord 4, autoriteit 3%

Wat dacht je van:

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]

Antwoord 5

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

Antwoord 6

more_itertools.locatevindt indices voor alle items die aan een voorwaarde voldoen.

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_itertoolsis een externe bibliotheek > pip install more_itertools.


Antwoord 7

Of gebruik range(python 3):

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

Voor (python 2):

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

En dan (beide gevallen):

print(l)

Is zoals verwacht.


Antwoord 8

import numpy as np
import random  # to create test list
# create sample list
random.seed(365)
l = [random.choice(['s1', 's2', 's3', 's4']) for _ in range(20)]
# convert the list to an array for use with these numpy methods
a = np.array(l)
# create a dict of each unique entry and the associated indices
idx = {v: np.where(a == v)[0].tolist() for v in np.unique(a)}
# print(idx)
{'s1': [7, 9, 10, 11, 17],
 's2': [1, 3, 6, 8, 14, 18, 19],
 's3': [0, 2, 13, 16],
 's4': [4, 5, 12, 15]}
# find a single element with 
idx = np.where(a == 's1')
print(idx)
[out]:
(array([ 7,  9, 10, 11, 17], dtype=int64),)

%timeit

# create 2M element list
random.seed(365)
l = [random.choice(['s1', 's2', 's3', 's4']) for _ in range(2000000)]
# create array
a = np.array(l)

Zoek de indices van één waarde

  • Zoek indices van een enkel element in een 2M elementenlijst met 4 unieke elementen
# np.where
%timeit np.where(a == 's1')
[out]:
25.9 ms ± 827 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
# list-comprehension
%timeit [i for i, x in enumerate(l) if x == "s1"]
[out]:
175 ms ± 2.73 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
# filter
%timeit list(filter(lambda i: a[i]=="s1", range(len(a))))
[out]:
925 ms ± 10.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Zoek de indices van alle waarden

  • Vind indexen van alle unieke elementen in een 2M elementenlijst met 4 unieke elementen
# use np.where and np.unique
%timeit {v: np.where(a == v)[0].tolist() for v in np.unique(a)}
[out]:
312 ms ± 9.13 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# list comprehension inside dict comprehension
%timeit {req_word: [idx for idx, word in enumerate(a) if word == req_word] for req_word in set(a)}
[out]:
3.72 s ± 21.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Antwoord 9

Nog een oplossing (sorry als het dubbel voorkomt) voor alle gevallen:

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)

Antwoord 10

Alle exemplaren en de positie van een of meer (identieke) items in een lijst ophalen

Met enumerate(alist) kun je het eerste element (n) dat de index van de lijst is, opslaan als het element x gelijk is aan wat je zoekt.

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

Laten we onze functie findindex maken

Deze functie neemt het item en de lijst als argumenten en retourneert de positie van het item in de lijst, zoals we eerder zagen.

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

Uitvoer


[1, 3, 5, 7]

Eenvoudig

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

Uitvoer:

0
4

Antwoord 11

Filter() gebruiken in 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]

Antwoord 12

U kunt een standaarddictaat maken

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)

Antwoord 13

Een for-loopgebruiken:

  • Antwoorden met enumerateen een lijst begripzijn meer pythonisch, niet noodzakelijkerwijs sneller. Dit antwoord is echter bedoeld voor studenten die sommige van die ingebouwde in functies.
  • maak een lege lijst, indices
  • maak de lus met for i in range(len(x)):, die in wezen door een lijst met indexlocaties loopt [0, 1, 2, 3, ..., len(x)-1]
  • voeg in de loop een willekeurige itoe, waarbij x[i]een overeenkomst is met value, aan indices
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]
  • De functies, get_indices, zijn geïmplementeerd met het type hints. In dit geval is de lijst, n, een stel ints, daarom zoeken we naar value, ook gedefinieerd als een int.

Een while-loopen .indexgebruiken:

  • Gebruik bij .indextry-exceptvoor foutafhandeling, omdat er een ValueErrorzal optreden als valueniet in de liststaat .
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]

Antwoord 14

Als je Python 2 gebruikt, kun je hiermee dezelfde functionaliteit bereiken:

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

Waarbij my_listde lijst is waarvan u de indexen wilt krijgen, en valuede gezochte waarde is. Gebruik:

f(some_list, some_element)

Antwoord 15

Als u moet zoeken naar de posities van alle elementen tussen bepaalde indices, kunt u deze aangeven:

[i for i,x in enumerate([1,2,3,2]) if x==2 & 2<= i <=3] # -> [3]

Antwoord 16

Een op dynamische lijst gebaseerde oplossing voor het geval we niet van tevoren weten welk element:

lst = ['to', 'be', 'or', 'not', 'to', 'be']
{req_word: [idx for idx, word in enumerate(lst) if word == req_word] for req_word in set(lst)}

resulteert in:

{'be': [1, 5], 'or': [2], 'to': [0, 4], 'not': [3]}

Je kunt alle andere manieren in dezelfde lijn bedenken, maar met index()kun je maar één index vinden, hoewel je het nummer van het voorkomen zelf kunt instellen.


Antwoord 17

Hier is een tijdprestatievergelijking tussen het gebruik van np.whereversus list_comprehension. Het lijkt erop dat np.wheregemiddeld sneller is.

# np.where
start_times = []
end_times = []
for i in range(10000):
    start = time.time()
    start_times.append(start)
    temp_list = np.array([1,2,3,3,5])
    ixs = np.where(temp_list==3)[0].tolist()
    end = time.time()
    end_times.append(end)
print("Took on average {} seconds".format(
    np.mean(end_times)-np.mean(start_times)))
Took on average 3.81469726562e-06 seconds
# list_comprehension
start_times = []
end_times = []
for i in range(10000):
    start = time.time()
    start_times.append(start)
    temp_list = np.array([1,2,3,3,5])
    ixs = [i for i in range(len(temp_list)) if temp_list[i]==3]
    end = time.time()
    end_times.append(end)
print("Took on average {} seconds".format(
    np.mean(end_times)-np.mean(start_times)))
Took on average 4.05311584473e-06 seconds

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes