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"]
enumeratedi 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, numpysangat 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 wheremengembalikan tuple(array([2, 8], dtype=int64),)
all_id_resp_addressseharusnya np.arraytidak list.
listdan str, jelas Anda lulus Falseke np.where. Ketika Anda membandingkan np.arraydengan sesuatu Anda mendapatkan array nilai boolean. Kemudian np.wheretemukan posisi semua Truenilai 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 numpysolusi 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.timeitdaftar 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_itertoolsadalah perpustakaan pihak ketiga > pip install more_itertools.
conda installtelah 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:enumeratedan pemahaman daftar lebih efisien dan pythonic, namun, jawaban ini ditujukan untuk siswa yang mungkin tidak diizinkan untuk menggunakan beberapa fungsi bawaan tersebut .indicesfor 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_indicesdiimplementasikan dengan petunjuk jenis . Dalam hal ini, daftar,, nadalah sekelompok ints, oleh karena itu kami mencari value, juga didefinisikan sebagai int.while-loopdan .index:.index, gunakan try-exceptuntuk penanganan kesalahan karena ValueErrorakan terjadi jika valuetidak 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_indeicessedikit 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_listdaftar Anda ingin mendapatkan indeks, dan valueadalah 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]