Saya agak bingung dengan pertanyaan ini: apakah Anda ingin mencari item secara rekursif di semua tingkat daftar multidimensi, atau apakah Anda hanya ingin mencari kejadian di tingkat atas daftar?
Anderson Green
22
Menurut pendapat saya harus ada metode daftar yang melakukan ini.
otocan
Jawaban:
545
Anda dapat menggunakan pemahaman daftar:
indices =[i for i, x in enumerate(my_list)if x =="whatever"]
Pada ular sanca yang lebih tua, gunakan filter () untuk fungsionalitas yang pada dasarnya sama.
Gleno
44
Pemahaman daftar muncul dalam python di 2.0, enumeratedi 2.3. Jadi ya, jika Python Anda kuno, gunakan filter().
Steven Rumbalski
2
Teknik ini tidak akan menemukan semua kemunculan item dalam array multidimensi. Misalnya, print([i for i, x in enumerate([[1,1],[0,1]]) if x == 1])mengembalikan []bukan [[0, 1], [0, 0], [1, 1]].
Anderson Green
10
@AndersonGreen: Istilah "array multidimensi" menunjukkan struktur data yang dijamin memiliki ukuran seragam di sepanjang masing-masing kapaknya. Tidak ada struktur data seperti itu di Python biasa. Ada daftar daftar, tetapi mereka sangat berbeda dari "array multidimensi". Jika Anda menginginkan yang terakhir, Anda harus mempertimbangkan menggunakan NumPy, yang memungkinkan Anda melakukan hal-hal seperti (a == 1).nonzero()untuk array NumPy a.
Sven Marnach
2
@MadmanLee Jika Anda menginginkan sesuatu yang cepat, gunakan NumPy. Lihat jawaban JoshAdel
Georgy
117
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.
Saya perhatikan [0] pada akhirnya mengubah apa yang akan menjadi array ke string. Saya ingin tahu mengapa Anda memilih untuk melakukan ini.
amelia
5
@amelia [0]diperlukan karena akan wheremengembalikan tuple(array([2, 8], dtype=int64),)
Winand
1
Hey @ Win dan saya memasukkan [0] tetapi masih mendapatkan kedua bagian. Ini kode saya: (nrg.local_logs.all_id_resp_address adalah daftar) "ste =" 199.38.164.165 "value = np.where (nrg.local_logs.all_id_resp_address == ste) [0]" Saya akan senang jika Anda dapat memberi tahu saya apa yang saya lakukan salah
@Tomer Anda mencoba untuk membandingkan 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.
Menangkan dan
29
Solusi menggunakan list.index:
def indices(lst, element):
result =[]
offset =-1whileTrue:try:
offset = lst.index(element, offset+1)exceptValueError: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.
Anda mengatakan ini lebih cepat dari daftar comp, dapatkah Anda menunjukkan timing Anda yang menunjukkan ini?
Chris_Rands
5
Ini sudah lama sekali, saya mungkin menggunakan 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.
Paulo Almeida
18
Bagaimana tentang:
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]
Mendapatkan semua kemunculan dan posisi satu atau lebih item (identik) dalam daftar
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]>>>
Mari kita buat fungsi kita temukan indeks
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]
Sederhana
for n, i in enumerate([1,2,3,4,1]):if i ==1:print(n)
Jawaban ini adalah yang paling mudah bagi saya untuk menerapkan kode saya yang ada.
Ryan Harris
2
Menggunakan for-loop:
Jawaban dengan enumeratedan pemahaman daftar lebih efisien dan pythonic, namun, jawaban ini ditujukan untuk siswa yang mungkin tidak diizinkan untuk menggunakan beberapa fungsi bawaan tersebut .
buat daftar kosong, indices
buat loop dengan for i in range(len(x)):, yang pada dasarnya beralih melalui daftar lokasi indeks[0, 1, 2, 3, ..., len(x)-1]
dalam loop, tambahkan 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]
Fungsi,, get_indicesdiimplementasikan dengan petunjuk jenis . Dalam hal ini, daftar,, nadalah sekelompok ints, oleh karena itu kami mencari value, juga didefinisikan sebagai int.
Menggunakan a while-loopdan .index:
Dengan .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 =0whileTrue: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 +=1exceptValueErroras e:breakreturn indices
print(get_indices(n,-60))>>>[4,8,9]
Jawaban:
Anda dapat menggunakan pemahaman daftar:
sumber
enumerate
di 2.3. Jadi ya, jika Python Anda kuno, gunakanfilter()
.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 NumPya
.Meskipun bukan solusi untuk daftar secara langsung,
numpy
sangat bersinar untuk hal semacam ini:pengembalian:
Ini bisa secara signifikan lebih cepat untuk daftar (array) dengan sejumlah besar elemen vs beberapa solusi lainnya.
sumber
[0]
diperlukan karena akanwhere
mengembalikan tuple(array([2, 8], dtype=int64),)
all_id_resp_address
seharusnyanp.array
tidaklist
.list
danstr
, jelas Anda lulusFalse
kenp.where
. Ketika Anda membandingkannp.array
dengan sesuatu Anda mendapatkan array nilai boolean. Kemudiannp.where
temukan posisi semuaTrue
nilai array itu.Solusi menggunakan
list.index
:Ini jauh lebih cepat daripada pemahaman daftar
enumerate
, untuk daftar besar. Ini juga jauh lebih lambat daripadanumpy
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.
sumber
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.Bagaimana tentang:
sumber
sumber
more_itertools.locate
menemukan indeks untuk semua item yang memenuhi syarat.more_itertools
adalah perpustakaan pihak ketiga> pip install more_itertools
.sumber
conda install
telah berubah sangat tidak stabil dalam kinerja akhir-akhir ini)Satu lagi solusi (maaf jika duplikat) untuk semua kejadian:
sumber
Atau Gunakan
range
(python 3):Untuk (python 2):
Dan kemudian (kedua kasus):
Seperti yang diharapkan.
sumber
Menggunakan filter () di python2.
sumber
Anda dapat membuat defaultdict
sumber
Mendapatkan semua kemunculan dan posisi satu atau lebih item (identik) dalam daftar
Dengan enumerate (daftar) Anda dapat menyimpan elemen pertama (n) yang merupakan indeks daftar ketika elemen x sama dengan apa yang Anda cari.
Mari kita buat fungsi kita temukan indeks
Fungsi ini mengambil item dan daftar sebagai argumen dan mengembalikan posisi item dalam daftar, seperti yang kita lihat sebelumnya.
Keluaran
Sederhana
Keluaran:
sumber
Menggunakan
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 manax[i]
cocok denganvalue
, keindices
x[i]
mengakses daftar berdasarkan indeksget_indices
diimplementasikan dengan petunjuk jenis . Dalam hal ini, daftar,,n
adalah sekelompokint
s, oleh karena itu kami mencarivalue
, juga didefinisikan sebagaiint
.Menggunakan a
while-loop
dan.index
:.index
, gunakantry-except
untuk penanganan kesalahan karenaValueError
akan terjadi jikavalue
tidak ada dalam daftar.sumber
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:
Di mana
my_list
daftar Anda ingin mendapatkan indeks, danvalue
adalah nilai yang dicari. Pemakaian:sumber
Jika Anda perlu mencari posisi semua elemen di antara indeks tertentu , Anda dapat menyatakannya:
sumber