index()
hanya akan memberikan kemunculan pertama item dalam daftar. Apakah ada trik rapi yang mengembalikan semua indeks dalam daftar?
index()
hanya akan memberikan kemunculan pertama item dalam daftar. Apakah ada trik rapi yang mengembalikan semua indeks dalam daftar?
Jawaban:
Anda dapat menggunakan pemahaman daftar:
indices = [i for i, x in enumerate(my_list) if x == "whatever"]
enumerate
di 2.3. Jadi ya, jika Python Anda kuno, gunakan filter()
.
print([i for i, x in enumerate([[1,1],[0,1]]) if x == 1])
mengembalikan []
bukan [[0, 1], [0, 0], [1, 1]]
.
(a == 1).nonzero()
untuk array NumPy a
.
Meskipun bukan solusi untuk daftar secara langsung, numpy
sangat bersinar untuk hal semacam ini:
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]
pengembalian:
ii ==>array([2, 8])
Ini bisa secara signifikan lebih cepat untuk daftar (array) dengan sejumlah besar elemen vs beberapa solusi lainnya.
[0]
diperlukan karena akan where
mengembalikan tuple(array([2, 8], dtype=int64),)
all_id_resp_address
seharusnya np.array
tidak list
.
list
dan str
, jelas Anda lulus False
ke np.where
. Ketika Anda membandingkan np.array
dengan sesuatu Anda mendapatkan array nilai boolean. Kemudian np.where
temukan posisi semua True
nilai array itu.
Solusi menggunakan 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)
Ini jauh lebih cepat daripada pemahaman daftar enumerate
, untuk daftar besar. Ini juga jauh lebih lambat daripada numpy
solusi jika Anda sudah memiliki array, jika tidak biaya konversi melebihi kenaikan kecepatan (diuji pada daftar bilangan bulat dengan elemen 100, 1000 dan 10000).
CATATAN: Catatan kehati-hatian berdasarkan komentar Chris_Rands: solusi ini lebih cepat dari pemahaman daftar jika hasilnya cukup jarang, tetapi jika daftar memiliki banyak contoh elemen yang sedang dicari (lebih dari ~ 15% dari daftar) , pada tes dengan daftar 1000 bilangan bulat), pemahaman daftar lebih cepat.
timeit.timeit
daftar yang dibuat secara acak. Tapi itu poin penting, dan saya kira itu sebabnya Anda bertanya. Pada saat itu tidak terpikir oleh saya, tetapi peningkatan kecepatan hanya benar jika hasilnya cukup jarang. Saya baru saja menguji dengan daftar penuh elemen untuk mencari, dan itu jauh lebih lambat daripada pemahaman daftar.
more_itertools.locate
menemukan indeks untuk semua item yang memenuhi syarat.
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
adalah perpustakaan pihak ketiga > pip install more_itertools
.
conda install
telah berubah sangat tidak stabil dalam kinerja akhir-akhir ini)
Satu lagi solusi (maaf jika duplikat) untuk semua kejadian:
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)
Menggunakan filter () di 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]
Anda dapat membuat 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)
Dengan enumerate (daftar) Anda dapat menyimpan elemen pertama (n) yang merupakan indeks daftar ketika elemen x sama dengan apa yang Anda cari.
>>> alist = ['foo', 'spam', 'egg', 'foo']
>>> foo_indexes = [n for n,x in enumerate(alist) if x=='foo']
>>> foo_indexes
[0, 3]
>>>
Fungsi ini mengambil item dan daftar sebagai argumen dan mengembalikan posisi item dalam daftar, seperti yang kita lihat sebelumnya.
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"))
Keluaran
[1, 3, 5, 7]
for n, i in enumerate([1, 2, 3, 4, 1]):
if i == 1:
print(n)
Keluaran:
0
4
for-loop
:enumerate
dan pemahaman daftar lebih efisien dan pythonic, namun, jawaban ini ditujukan untuk siswa yang mungkin tidak diizinkan untuk menggunakan beberapa fungsi bawaan tersebut .indices
for i in range(len(x)):
, yang pada dasarnya beralih melalui daftar lokasi indeks[0, 1, 2, 3, ..., len(x)-1]
i
, di mana x[i]
cocok dengan value
, keindices
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_indices
diimplementasikan dengan petunjuk jenis . Dalam hal ini, daftar,, n
adalah sekelompok int
s, oleh karena itu kami mencari value
, juga didefinisikan sebagai int
.while-loop
dan .index
:.index
, gunakan try-except
untuk penanganan kesalahan karena ValueError
akan terjadi jika value
tidak ada dalam daftar.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
sedikit lebih cepat (~ 15%) daripada pemahaman daftar normal. Saya mencoba mencari tahu.
Jika Anda menggunakan Python 2, Anda dapat mencapai fungsi yang sama dengan ini:
f = lambda my_list, value:filter(lambda x: my_list[x] == value, range(len(my_list)))
Di mana my_list
daftar Anda ingin mendapatkan indeks, dan value
adalah nilai yang dicari. Pemakaian:
f(some_list, some_element)
Jika Anda perlu mencari posisi semua elemen di antara indeks tertentu , Anda dapat menyatakannya:
[i for i,x in enumerate([1,2,3,2]) if x==2 & 2<= i <=3] # -> [3]