Apakah Anda kembali: [1] Indeks terendah jika ada beberapa contoh "bar", [2] Semua indeks "bar"?
ǻňạgǻňạcểơửṩ
4
a) Apakah dijamin barang itu ada dalam daftar, atau bagaimana kita harus menangani kasus kesalahan? (tidak ada pengembalian / naikkan ValueError) b) Apakah entri daftar dijamin unik, dan haruskah kita mengembalikan indeks pertandingan yang pertama, atau semua indeks?
smci
Lihat jawaban dengan integrasi numpy, array numpy jauh lebih efisien daripada daftar Python. Jika daftar ini pendek, maka tidak masalah membuat salinannya dari daftar Python, jika tidak maka mungkin Anda harus mempertimbangkan untuk menyimpan elemen-elemen dalam array numpy di tempat pertama.
Perhatikan bahwa meskipun ini mungkin cara paling bersih untuk menjawab pertanyaan yang diajukan , indexadalah komponen yang agak lemah dari listAPI, dan saya tidak ingat kapan terakhir kali saya menggunakannya dalam kemarahan. Sudah ditunjukkan kepada saya di komentar bahwa karena jawaban ini sangat direferensikan, itu harus dibuat lebih lengkap. Beberapa peringatan tentang list.indexmengikuti. Mungkin ada baiknya melihat pada dokumentasi untuk itu:
list.index(x[, start[, end]])
Kembalikan indeks berbasis nol dalam daftar item pertama yang nilainya sama dengan x . Meningkatkan ValueErrorjika tidak ada item seperti itu.
Argumen opsional mulai dan berakhir ditafsirkan sebagai dalam notasi slice dan digunakan untuk membatasi pencarian untuk urutan tertentu dari daftar. Indeks yang dikembalikan dihitung relatif terhadap awal urutan penuh daripada argumen awal.
Linear-kompleksitas waktu dalam panjang daftar
Suatu indexpanggilan memeriksa setiap elemen daftar secara berurutan, sampai menemukan kecocokan. Jika daftar Anda panjang, dan Anda tidak tahu secara kasar di mana dalam daftar itu terjadi, pencarian ini bisa menjadi hambatan. Dalam hal ini, Anda harus mempertimbangkan struktur data yang berbeda. Perhatikan bahwa jika Anda tahu kira-kira di mana menemukan kecocokan, Anda bisa memberikan indexpetunjuk. Misalnya, dalam cuplikan ini, l.index(999_999, 999_990, 1_000_000)kira-kira lima urutan besarnya lebih cepat daripada lurus l.index(999_999), karena yang pertama hanya perlu mencari 10 entri, sedangkan yang terakhir mencari satu juta:
Hanya mengembalikan indeks kecocokan pertama ke argumennya
Panggilan untuk indexmencari melalui daftar untuk menemukan kecocokan, dan berhenti di sana. Jika Anda berharap membutuhkan indeks lebih banyak kecocokan, Anda harus menggunakan pemahaman daftar, atau ekspresi generator.
>>>[1,1].index(1)0>>>[i for i, e in enumerate([1,2,1])if e ==1][0,2]>>> g =(i for i, e in enumerate([1,2,1])if e ==1)>>> next(g)0>>> next(g)2
Sebagian besar tempat di mana saya pernah akan digunakan index, saya sekarang menggunakan pemahaman daftar atau ekspresi generator karena mereka lebih digeneralisasikan. Jadi jika Anda mempertimbangkan untuk meraihnya index, lihatlah fitur-fitur Python yang luar biasa ini.
Melempar jika elemen tidak ada dalam daftar
Panggilan untuk indexmenghasilkan ValueErrorjika item itu tidak ada.
>>>[1,1].index(2)Traceback(most recent call last):File"<stdin>", line 1,in<module>ValueError:2isnotin list
Jika item itu mungkin tidak ada dalam daftar, Anda juga harus
Periksa terlebih dahulu dengan item in my_list(pendekatan bersih, dapat dibaca), atau
Bungkus indexpanggilan dalam try/exceptblok yang menangkap ValueError(mungkin lebih cepat, setidaknya ketika daftar untuk pencarian panjang, dan item biasanya ada.)
index mengembalikan item pertama yang nilainya "bar". Jika "bilah" ada dua kali pada daftar, Anda tidak akan pernah menemukan kunci untuk "bilah" kedua. Lihat dokumentasi: docs.python.org/3/tutorial/datastructures.html
mpoletto
2
Jika Anda hanya mencari satu elemen (yang pertama), saya menemukan bahwa index()hanya di bawah 90% lebih cepat dari daftar pemahaman terhadap daftar bilangan bulat.
slybloty
Struktur data apa yang harus digunakan jika daftar sangat panjang?
izhang05
@izhang: Beberapa indeks tambahan, seperti dikt {elemen -> list_index}, jika elemen hashable, dan posisi dalam daftar penting.
Alex Coventry
899
Satu hal yang sangat membantu dalam mempelajari Python adalah menggunakan fungsi bantuan interaktif:
>>> help(["foo","bar","baz"])Help on list object:class list(object)...|| index(...)| L.index(value,[start,[stop]])-> integer --return first index of value|
yang akan sering mengarahkan Anda ke metode yang Anda cari.
bpython adalah cara ramah-pengguna yang bagus untuk membaca dokumen secara interaktif.
goetzc
@davidavr ya, tapi kemudian kita semua yang hanya ingin google saja daripada menggulir melalui help docs tidak akan memiliki set opsi yang bagus, sentral, dan berperingkat ini. :)
honkaboy
556
Mayoritas jawaban menjelaskan cara menemukan indeks tunggal , tetapi metode mereka tidak mengembalikan banyak indeks jika item ada dalam daftar beberapa kali. Gunakan enumerate():
for i, j in enumerate(['foo','bar','baz']):if j =='bar':print(i)
The index()fungsi hanya mengembalikan kejadian pertama, sementara enumerate()mengembalikan semua kejadian.
Sebagai pemahaman daftar:
[i for i, j in enumerate(['foo','bar','baz'])if j =='bar']
Berikut ini juga solusi kecil lainnya itertools.count()(yang hampir sama dengan pendekatan penghitungan):
from itertools import izip as zip, count # izip for maximum efficiency[i for i, j in zip(count(),['foo','bar','baz'])if j =='bar']
Ini lebih efisien untuk daftar yang lebih besar daripada menggunakan enumerate():
$ python -m timeit -s "from itertools import izip as zip, count""[i for i, j in zip(count(), ['foo', 'bar', 'baz']*500) if j == 'bar']"10000 loops, best of 3:174 usec per loop
$ python -m timeit "[i for i, j in enumerate(['foo', 'bar', 'baz']*500) if j == 'bar']"10000 loops, best of 3:196 usec per loop
Pencacahan bekerja lebih baik daripada metode berbasis indeks untuk saya, karena saya mencari untuk mengumpulkan indeks string menggunakan 'startswith ", dan saya perlu mengumpulkan beberapa kejadian. Atau apakah ada cara untuk menggunakan indeks dengan" startswith "yang saya tidak tahu
Tupelo Thistlehead
3
Di tangan saya, versi enumerasi secara konsisten sedikit lebih cepat. Beberapa detail implementasi mungkin telah berubah sejak pengukuran di atas diposting.
Masalah akan muncul jika elemen tidak ada dalam daftar. Fungsi ini menangani masalah:
# if element is found it returns index of element else returns Nonedef find_element_in_list(element, list_element):try:
index_element = list_element.index(element)return index_elementexceptValueError:returnNone
Namun, itu mungkin menggandakan kompleksitas. Adakah yang memeriksa?
stefanct
@stefanct Kompleksitas waktu masih linier tetapi akan beralih melalui daftar dua kali.
ApproachingDarknessFish
@ApproachingDarknessFish Jelas itu yang saya maksud. Bahkan jika secara pedantik itu adalah urutan kompleksitas yang sama, iterasi dua kali mungkin merupakan kerugian besar dalam banyak kasus penggunaan sehingga saya membawanya. Dan kita masih belum tahu jawabannya ...
stefanct
44
Semua fungsi yang diusulkan di sini mereproduksi perilaku bahasa bawaan tetapi mengaburkan apa yang terjadi.
[i for i in range(len(mylist))if mylist[i]==myterm]# get the indices[each for each in mylist if each==myterm]# get the items
mylist.index(myterm)if myterm in mylist elseNone# get the first index and fail quietly
Mengapa menulis fungsi dengan penanganan pengecualian jika bahasa tersebut menyediakan metode untuk melakukan apa yang Anda inginkan?
Re: "Semua fungsi yang diusulkan di sini" : Pada saat penulisan mungkin, tetapi Anda harus memeriksa jawaban yang lebih baru untuk melihat apakah itu masih benar.
Peter Mortensen
41
Jika Anda ingin semua indeks, maka Anda dapat menggunakan NumPy :
Ini yang terbaik yang pernah saya baca. array numpy jauh lebih efisien daripada daftar Python. Jika daftar ini pendek, maka tidak masalah membuat salinannya dari daftar Python, jika tidak maka mungkin pengembang harus mempertimbangkan untuk menyimpan elemen-elemen dalam array numpy di tempat pertama.
Athanassios
35
Menemukan indeks dari suatu item diberi daftar berisi itu dengan Python
Untuk daftar ["foo", "bar", "baz"]dan item dalam daftar "bar", apa cara paling bersih untuk mendapatkan indeksnya (1) dengan Python?
Ya, tentu saja, ada metode indeks, yang mengembalikan indeks kejadian pertama:
>>> l =["foo","bar","baz"]>>> l.index('bar')1
Ada beberapa masalah dengan metode ini:
jika nilainya tidak ada dalam daftar, Anda akan mendapatkan a ValueError
jika lebih dari satu nilai ada dalam daftar, Anda hanya mendapatkan indeks untuk yang pertama
Tidak ada nilai
Jika nilainya bisa hilang, Anda perlu menangkap ValueError.
Anda dapat melakukannya dengan definisi yang dapat digunakan kembali seperti ini:
Dan kelemahan dari ini adalah bahwa Anda mungkin akan memeriksa apakah nilai yang dikembalikan isatau is notTidak ada:
result = index(a_list, value)if result isnotNone:
do_something(result)
Lebih dari satu nilai dalam daftar
Jika Anda dapat memiliki lebih banyak kejadian, Anda tidak akan mendapatkan informasi lengkap dengan list.index:
>>> l.append('bar')>>> l
['foo','bar','baz','bar']>>> l.index('bar')# nothing at index 3?1
Anda dapat menyebutkan daftar pemahaman indeks:
>>>[index for index, v in enumerate(l)if v =='bar'][1,3]>>>[index for index, v in enumerate(l)if v =='boink'][]
Jika Anda tidak memiliki kejadian, Anda dapat memeriksanya dengan boolean memeriksa hasilnya, atau hanya melakukan apa-apa jika Anda mengulangi hasilnya:
indexes =[index for index, v in enumerate(l)if v =='boink']for index in indexes:
do_something(index)
Data yang lebih baik munging dengan panda
Jika Anda memiliki panda, Anda dapat dengan mudah mendapatkan informasi ini dengan objek Seri:
>>>import pandas as pd
>>> series = pd.Series(l)>>> series
0 foo
1 bar
2 baz
3 bar
dtype: object
Pemeriksaan perbandingan akan menghasilkan serangkaian boolean:
>>> series =='bar'0False1True2False3True
dtype: bool
Serahkan seri boolean ke seri melalui notasi subskrip, dan Anda hanya mendapatkan anggota yang cocok:
>>> series[series =='bar']1 bar
3 bar
dtype: object
Jika Anda hanya menginginkan indeks, atribut indeks mengembalikan serangkaian bilangan bulat:
Dan jika Anda ingin mereka dalam daftar atau tuple, cukup berikan kepada konstruktor:
>>> list(series[series =='bar'].index)[1,3]
Ya, Anda bisa menggunakan daftar pemahaman dengan penghitungan juga, tapi itu tidak elegan, menurut pendapat saya - Anda melakukan tes untuk kesetaraan dengan Python, daripada membiarkan kode bawaan yang ditulis dalam C menanganinya:
>>>[i for i, value in enumerate(l)if value =='bar'][1,3]
Masalah XY adalah bertanya tentang solusi upaya Anda daripada masalah Anda yang sebenarnya.
Menurut Anda mengapa Anda membutuhkan indeks yang diberikan elemen dalam daftar?
Jika Anda sudah tahu nilainya, mengapa Anda peduli di mana itu ada dalam daftar?
Jika nilainya tidak ada, menangkapnya ValueErroragak bertele-tele - dan saya lebih suka menghindarinya.
Lagi pula, saya biasanya mengulang daftar, jadi saya biasanya akan menyimpan pointer ke informasi menarik, mendapatkan indeks dengan penghitungan.
Jika Anda munging data, Anda mungkin harus menggunakan panda - yang memiliki alat jauh lebih elegan daripada solusi Python murni yang saya tunjukkan.
Saya tidak ingat perlu list.index, sendiri. Namun, saya telah melihat melalui perpustakaan standar Python, dan saya melihat beberapa kegunaan yang sangat baik untuk itu.
Ada banyak, banyak kegunaannya idlelib, untuk GUI dan penguraian teks.
The keywordmodul menggunakan itu untuk menemukan penanda komentar dalam modul untuk secara otomatis menumbuhkan daftar kata kunci di dalamnya melalui metaprogramming.
Di Lib / mailbox.py tampaknya menggunakannya seperti pemetaan yang diurutkan:
key_list[key_list.index(old)]= new
dan
del key_list[key_list.index(key)]
Di Lib / http / cookiejar.py, tampaknya akan digunakan untuk mendapatkan bulan berikutnya:
mon = MONTHS_LOWER.index(mon.lower())+1
Di Lib / tarfile.py mirip dengan distutils untuk mendapatkan irisan hingga item:
members = members[:members.index(tarinfo)]
Di Lib / pickletools.py:
numtopop = before.index(markobject)
Kesamaan penggunaan ini adalah bahwa mereka tampaknya beroperasi pada daftar ukuran terbatas (penting karena O (n) waktu pencarian list.index), dan mereka sebagian besar digunakan dalam parsing (dan UI dalam kasus Idle).
Meskipun ada kasus penggunaan untuk itu, mereka cukup jarang. Jika Anda menemukan diri Anda mencari jawaban ini, tanyakan pada diri sendiri apakah yang Anda lakukan adalah penggunaan paling langsung dari alat yang disediakan oleh bahasa untuk kasus penggunaan Anda.
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)
>>> a =['red','blue','green','red']>>> b ='red'>>> offset =0;>>> indices = list()>>>for i in range(a.count(b)):... indices.append(a.index(b,offset))... offset = indices[-1]+1...>>> indices
[0,3]>>>
Dan sekarang, untuk sesuatu yang sangat berbeda ...
... seperti mengonfirmasi keberadaan item sebelum mendapatkan indeks. Yang menyenangkan tentang pendekatan ini adalah fungsi selalu mengembalikan daftar indeks - bahkan jika itu adalah daftar kosong. Ini bekerja dengan string juga.
def indices(l, val):"""Always returns a list containing the indices of val in the_list"""
retval =[]
last =0while val in l[last:]:
i = l[last:].index(val)
retval.append(last + i)
last += i +1return retval
l =['bar','foo','bar','baz','bar','bar']
q ='bar'print indices(l,q)print indices(l,'bat')print indices('abcdaababb','a')
Ketika disisipkan ke jendela python interaktif:
Python2.7.6(v2.7.6:3a1db0d2747e,Nov102013,00:42:54)[GCC 4.2.1(AppleInc. build 5666)(dot 3)] on darwin
Type"help","copyright","credits"or"license"for more information.>>>def indices(the_list, val):..."""Always returns a list containing the indices of val in the_list"""... retval =[]... last =0...while val in the_list[last:]:... i = the_list[last:].index(val)... retval.append(last + i)... last += i +1...return retval
...>>> l =['bar','foo','bar','baz','bar','bar']>>> q ='bar'>>>print indices(l,q)[0,2,4,5]>>>print indices(l,'bat')[]>>>print indices('abcdaababb','a')[0,4,5,7]>>>
Memperbarui
Setelah satu tahun lagi pengembangan python head-down, saya agak malu dengan jawaban asli saya, jadi untuk meluruskan, seseorang tentu dapat menggunakan kode di atas; Namun, cara yang jauh lebih idiomatis untuk mendapatkan perilaku yang sama adalah dengan menggunakan pemahaman daftar, bersama dengan fungsi enumerate ().
Sesuatu seperti ini:
def indices(l, val):"""Always returns a list containing the indices of val in the_list"""return[index for index, value in enumerate(l)if value == val]
l =['bar','foo','bar','baz','bar','bar']
q ='bar'print indices(l,q)print indices(l,'bat')print indices('abcdaababb','a')
Yang, ketika disisipkan ke dalam jendela python interaktif menghasilkan:
Python2.7.14|Anaconda,Inc.|(default,Dec72017,11:07:58)[GCC 4.2.1CompatibleClang4.0.1(tags/RELEASE_401/final)] on darwin
Type"help","copyright","credits"or"license"for more information.>>>def indices(l, val):..."""Always returns a list containing the indices of val in the_list"""...return[index for index, value in enumerate(l)if value == val]...>>> l =['bar','foo','bar','baz','bar','bar']>>> q ='bar'>>>print indices(l,q)[0,2,4,5]>>>print indices(l,'bat')[]>>>print indices('abcdaababb','a')[0,4,5,7]>>>
Dan sekarang, setelah meninjau pertanyaan ini dan semua jawaban, saya menyadari bahwa inilah yang disarankan oleh FMc dalam jawaban sebelumnya . Pada saat saya awalnya menjawab pertanyaan ini, saya bahkan tidak melihat jawaban itu, karena saya tidak memahaminya. Saya berharap bahwa contoh saya yang agak lebih verbal akan membantu pemahaman.
Jika satu baris kode di atas masih tidak masuk akal bagi Anda, saya sangat merekomendasikan Anda 'pemahaman daftar python' Google dan membutuhkan waktu beberapa menit untuk membiasakan diri. Ini hanya salah satu dari banyak fitur canggih yang membuatnya senang menggunakan Python untuk mengembangkan kode.
Varian pada jawaban dari FMc dan user7177 akan memberikan dict yang dapat mengembalikan semua indeks untuk entri apa pun:
>>> a =['foo','bar','baz','bar','any','foo','much']>>> l = dict(zip(set(a), map(lambda y:[i for i,z in enumerate(a)if z is y ], set(a))))>>> l['foo'][0,5]>>> l ['much'][6]>>> l
{'baz':[2],'foo':[0,5],'bar':[1,3],'any':[4],'much':[6]}>>>
Anda juga bisa menggunakan ini sebagai satu liner untuk mendapatkan semua indeks untuk satu entri. Tidak ada jaminan untuk efisiensi, meskipun saya memang menggunakan set (a) untuk mengurangi berapa kali lambda dipanggil.
Solusi ini tidak sekuat yang lain, tetapi jika Anda seorang pemula dan hanya tahu tentang forloop, masih mungkin untuk menemukan indeks pertama dari suatu item sambil menghindari ValueError:
def find_element(p,t):
i =0for e in p:if e == t:return i
else:
i +=1return-1
[i for i, j in enumerate (tumpukan jerami) jika j == 'needle'] lebih ringkas dan mudah dibaca, saya kira.
Giovanni G. PY
5
name ="bar"
list =[["foo",1],["bar",2],["baz",3]]
new_list=[]for item in list:
new_list.append(item[0])print(new_list)try:
location= new_list.index(name)except:
location=-1print(location)
Ini menjelaskan jika string juga tidak ada dalam daftar, jika tidak ada dalam daftar location = -1
index()Metode Python melempar kesalahan jika item tidak ditemukan. Jadi alih-alih, Anda dapat membuatnya mirip dengan indexOf()fungsi JavaScript yang kembali -1jika item tidak ditemukan:
try:
index = array.index('search_keyword')exceptValueError:
index =-1
Namun, JavaScript memiliki filosofi bahwa hasil aneh lebih baik daripada kesalahan, jadi masuk akal untuk mengembalikan -1, tetapi dengan Python, itu bisa membuat sulit untuk melacak bug, karena -1 mengembalikan item dari akhir daftar.
Jawaban ini terasa di rumah untuk Scala/ penggemar pemrograman fungsional
y2k-shubham
3
Mari beri nama lstpada daftar yang Anda miliki. Orang dapat mengonversi daftar lstke a numpy array. Dan, kemudian gunakan numpy.where untuk mendapatkan indeks dari item yang dipilih dalam daftar. Mengikuti adalah cara di mana Anda akan mengimplementasikannya.
import numpy as np
lst =["foo","bar","baz"]#lst: : 'list' data typeprint np.where( np.array(lst)=='bar')[0][0]>>>1
Jika Anda akan menemukan indeks sekali maka menggunakan metode "indeks" baik-baik saja. Namun, jika Anda akan mencari data Anda lebih dari sekali maka saya sarankan menggunakan modul dua bagian . Perlu diingat bahwa menggunakan data modul dua bagian harus diurutkan. Jadi Anda mengurutkan data sekali dan kemudian Anda dapat menggunakan dua bagian. Menggunakan modul bisect pada mesin saya sekitar 20 kali lebih cepat daripada menggunakan metode indeks.
Berikut adalah contoh kode menggunakan sintaksis Python 3.8 dan di atas:
import bisect
from timeit import timeit
def bisect_search(container, value):return(
index
if(index := bisect.bisect_left(container, value))< len(container)and container[index]== value else-1)
data = list(range(1000))# value to search
value =666# times to test
ttt =1000
t1 = timeit(lambda: data.index(value), number=ttt)
t2 = timeit(lambda: bisect_search(data, value), number=ttt)print(f"{t1=:.4f}, {t2=:.4f}, diffs {t1/t2=:.2f}")
Disebutkan dalam berbagai jawaban bahwa metode list.index(item)metode bawaan adalah algoritma O (n). Tidak apa-apa jika Anda perlu melakukan ini sekali. Tetapi jika Anda perlu mengakses indeks elemen beberapa kali, lebih masuk akal untuk membuat kamus (O (n)) pertama dari pasangan item-indeks, dan kemudian mengakses indeks pada O (1) setiap kali Anda membutuhkan Itu.
Jika Anda yakin bahwa item dalam daftar Anda tidak pernah diulang, Anda dapat dengan mudah:
myList =["foo","bar","baz"]# Create the dictionary
myDict = dict((e,i)for i,e in enumerate(myList))# Lookup
myDict["bar"]# Returns 1# myDict.get("blah") if you don't want an error to be raised if element not found.
Jika Anda mungkin memiliki elemen duplikat, dan perlu mengembalikan semua indeksnya:
from collections import defaultdict as dd
myList =["foo","bar","bar","baz","foo"]# Create the dictionary
myDict = dd(list)for i,e in enumerate(myList):
myDict[e].append(i)# Lookup
myDict["foo"]# Returns [0, 4]
menurut saya ["foo", "bar", "baz"].index("bar")itu bagus tapi itu tidak cukup! karena jika "bar" tidak ada dalam kamus, ValueErrordinaikkan . Jadi Anda dapat menggunakan fungsi ini:
Jangan gunakan ini karena l = [1, 2]; find_index(l, 3)akan kembali -1dan l[find_index(l, 3)]akan kembali 2. -1 adalah hal yang buruk untuk kembali, hanya kembali Tidak ada.
Daniel Stracaboško
-1 adalah kontrak yang dapat Anda kembalikan apa pun yang Anda inginkan. Tetapi cobalah untuk menggunakan None yang lebih kecil dalam program Anda karena None atau Null dalam komunikasi program Anda dengan program lain seperti situs web android dan PHP dapat menyebabkan jeda program, misalnya Anda dapat mengembalikan nol di JSON dan aplikasi telepon situs web Anda akan ditutup atau mengembalikan Kesalahan 500 (kesalahan server internal).
"bar"
, [2] Semua indeks"bar"
?Jawaban:
Referensi: Struktur Data> Lebih Lanjut tentang Daftar
Peringatan diikuti
Perhatikan bahwa meskipun ini mungkin cara paling bersih untuk menjawab pertanyaan yang diajukan ,
index
adalah komponen yang agak lemah darilist
API, dan saya tidak ingat kapan terakhir kali saya menggunakannya dalam kemarahan. Sudah ditunjukkan kepada saya di komentar bahwa karena jawaban ini sangat direferensikan, itu harus dibuat lebih lengkap. Beberapa peringatan tentanglist.index
mengikuti. Mungkin ada baiknya melihat pada dokumentasi untuk itu:Linear-kompleksitas waktu dalam panjang daftar
Suatu
index
panggilan memeriksa setiap elemen daftar secara berurutan, sampai menemukan kecocokan. Jika daftar Anda panjang, dan Anda tidak tahu secara kasar di mana dalam daftar itu terjadi, pencarian ini bisa menjadi hambatan. Dalam hal ini, Anda harus mempertimbangkan struktur data yang berbeda. Perhatikan bahwa jika Anda tahu kira-kira di mana menemukan kecocokan, Anda bisa memberikanindex
petunjuk. Misalnya, dalam cuplikan ini,l.index(999_999, 999_990, 1_000_000)
kira-kira lima urutan besarnya lebih cepat daripada lurusl.index(999_999)
, karena yang pertama hanya perlu mencari 10 entri, sedangkan yang terakhir mencari satu juta:Hanya mengembalikan indeks kecocokan pertama ke argumennya
Panggilan untuk
index
mencari melalui daftar untuk menemukan kecocokan, dan berhenti di sana. Jika Anda berharap membutuhkan indeks lebih banyak kecocokan, Anda harus menggunakan pemahaman daftar, atau ekspresi generator.Sebagian besar tempat di mana saya pernah akan digunakan
index
, saya sekarang menggunakan pemahaman daftar atau ekspresi generator karena mereka lebih digeneralisasikan. Jadi jika Anda mempertimbangkan untuk meraihnyaindex
, lihatlah fitur-fitur Python yang luar biasa ini.Melempar jika elemen tidak ada dalam daftar
Panggilan untuk
index
menghasilkanValueError
jika item itu tidak ada.Jika item itu mungkin tidak ada dalam daftar, Anda juga harus
item in my_list
(pendekatan bersih, dapat dibaca), atauindex
panggilan dalamtry/except
blok yang menangkapValueError
(mungkin lebih cepat, setidaknya ketika daftar untuk pencarian panjang, dan item biasanya ada.)sumber
index()
hanya di bawah 90% lebih cepat dari daftar pemahaman terhadap daftar bilangan bulat.Satu hal yang sangat membantu dalam mempelajari Python adalah menggunakan fungsi bantuan interaktif:
yang akan sering mengarahkan Anda ke metode yang Anda cari.
sumber
Mayoritas jawaban menjelaskan cara menemukan indeks tunggal , tetapi metode mereka tidak mengembalikan banyak indeks jika item ada dalam daftar beberapa kali. Gunakan
enumerate()
:The
index()
fungsi hanya mengembalikan kejadian pertama, sementaraenumerate()
mengembalikan semua kejadian.Sebagai pemahaman daftar:
Berikut ini juga solusi kecil lainnya
itertools.count()
(yang hampir sama dengan pendekatan penghitungan):Ini lebih efisien untuk daftar yang lebih besar daripada menggunakan
enumerate()
:sumber
Untuk mendapatkan semua indeks:
sumber
index()
mengembalikan pertama indeks nilai!sumber
Masalah akan muncul jika elemen tidak ada dalam daftar. Fungsi ini menangani masalah:
sumber
sumber
Anda harus menetapkan kondisi untuk memeriksa apakah elemen yang Anda cari ada dalam daftar
sumber
Semua fungsi yang diusulkan di sini mereproduksi perilaku bahasa bawaan tetapi mengaburkan apa yang terjadi.
Mengapa menulis fungsi dengan penanganan pengecualian jika bahasa tersebut menyediakan metode untuk melakukan apa yang Anda inginkan?
sumber
Jika Anda ingin semua indeks, maka Anda dapat menggunakan NumPy :
Ini jelas, solusi yang mudah dibaca.
sumber
Ya, tentu saja, ada metode indeks, yang mengembalikan indeks kejadian pertama:
Ada beberapa masalah dengan metode ini:
ValueError
Tidak ada nilai
Jika nilainya bisa hilang, Anda perlu menangkap
ValueError
.Anda dapat melakukannya dengan definisi yang dapat digunakan kembali seperti ini:
Dan gunakan seperti ini:
Dan kelemahan dari ini adalah bahwa Anda mungkin akan memeriksa apakah nilai yang dikembalikan
is
atauis not
Tidak ada:Lebih dari satu nilai dalam daftar
Jika Anda dapat memiliki lebih banyak kejadian, Anda tidak akan mendapatkan informasi lengkap dengan
list.index
:Anda dapat menyebutkan daftar pemahaman indeks:
Jika Anda tidak memiliki kejadian, Anda dapat memeriksanya dengan boolean memeriksa hasilnya, atau hanya melakukan apa-apa jika Anda mengulangi hasilnya:
Data yang lebih baik munging dengan panda
Jika Anda memiliki panda, Anda dapat dengan mudah mendapatkan informasi ini dengan objek Seri:
Pemeriksaan perbandingan akan menghasilkan serangkaian boolean:
Serahkan seri boolean ke seri melalui notasi subskrip, dan Anda hanya mendapatkan anggota yang cocok:
Jika Anda hanya menginginkan indeks, atribut indeks mengembalikan serangkaian bilangan bulat:
Dan jika Anda ingin mereka dalam daftar atau tuple, cukup berikan kepada konstruktor:
Ya, Anda bisa menggunakan daftar pemahaman dengan penghitungan juga, tapi itu tidak elegan, menurut pendapat saya - Anda melakukan tes untuk kesetaraan dengan Python, daripada membiarkan kode bawaan yang ditulis dalam C menanganinya:
Apakah ini masalah XY ?
Menurut Anda mengapa Anda membutuhkan indeks yang diberikan elemen dalam daftar?
Jika Anda sudah tahu nilainya, mengapa Anda peduli di mana itu ada dalam daftar?
Jika nilainya tidak ada, menangkapnya
ValueError
agak bertele-tele - dan saya lebih suka menghindarinya.Lagi pula, saya biasanya mengulang daftar, jadi saya biasanya akan menyimpan pointer ke informasi menarik, mendapatkan indeks dengan penghitungan.
Jika Anda munging data, Anda mungkin harus menggunakan panda - yang memiliki alat jauh lebih elegan daripada solusi Python murni yang saya tunjukkan.
Saya tidak ingat perlu
list.index
, sendiri. Namun, saya telah melihat melalui perpustakaan standar Python, dan saya melihat beberapa kegunaan yang sangat baik untuk itu.Ada banyak, banyak kegunaannya
idlelib
, untuk GUI dan penguraian teks.The
keyword
modul menggunakan itu untuk menemukan penanda komentar dalam modul untuk secara otomatis menumbuhkan daftar kata kunci di dalamnya melalui metaprogramming.Di Lib / mailbox.py tampaknya menggunakannya seperti pemetaan yang diurutkan:
dan
Di Lib / http / cookiejar.py, tampaknya akan digunakan untuk mendapatkan bulan berikutnya:
Di Lib / tarfile.py mirip dengan distutils untuk mendapatkan irisan hingga item:
Di Lib / pickletools.py:
Kesamaan penggunaan ini adalah bahwa mereka tampaknya beroperasi pada daftar ukuran terbatas (penting karena O (n) waktu pencarian
list.index
), dan mereka sebagian besar digunakan dalam parsing (dan UI dalam kasus Idle).Meskipun ada kasus penggunaan untuk itu, mereka cukup jarang. Jika Anda menemukan diri Anda mencari jawaban ini, tanyakan pada diri sendiri apakah yang Anda lakukan adalah penggunaan paling langsung dari alat yang disediakan oleh bahasa untuk kasus penggunaan Anda.
sumber
Semua indeks dengan
zip
fungsi: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
Cukup Anda bisa pergi dengan
sumber
Pilihan lain
sumber
Dan sekarang, untuk sesuatu yang sangat berbeda ...
... seperti mengonfirmasi keberadaan item sebelum mendapatkan indeks. Yang menyenangkan tentang pendekatan ini adalah fungsi selalu mengembalikan daftar indeks - bahkan jika itu adalah daftar kosong. Ini bekerja dengan string juga.
Ketika disisipkan ke jendela python interaktif:
Memperbarui
Setelah satu tahun lagi pengembangan python head-down, saya agak malu dengan jawaban asli saya, jadi untuk meluruskan, seseorang tentu dapat menggunakan kode di atas; Namun, cara yang jauh lebih idiomatis untuk mendapatkan perilaku yang sama adalah dengan menggunakan pemahaman daftar, bersama dengan fungsi enumerate ().
Sesuatu seperti ini:
Yang, ketika disisipkan ke dalam jendela python interaktif menghasilkan:
Dan sekarang, setelah meninjau pertanyaan ini dan semua jawaban, saya menyadari bahwa inilah yang disarankan oleh FMc dalam jawaban sebelumnya . Pada saat saya awalnya menjawab pertanyaan ini, saya bahkan tidak melihat jawaban itu, karena saya tidak memahaminya. Saya berharap bahwa contoh saya yang agak lebih verbal akan membantu pemahaman.
Jika satu baris kode di atas masih tidak masuk akal bagi Anda, saya sangat merekomendasikan Anda 'pemahaman daftar python' Google dan membutuhkan waktu beberapa menit untuk membiasakan diri. Ini hanya salah satu dari banyak fitur canggih yang membuatnya senang menggunakan Python untuk mengembangkan kode.
sumber
Varian pada jawaban dari FMc dan user7177 akan memberikan dict yang dapat mengembalikan semua indeks untuk entri apa pun:
Anda juga bisa menggunakan ini sebagai satu liner untuk mendapatkan semua indeks untuk satu entri. Tidak ada jaminan untuk efisiensi, meskipun saya memang menggunakan set (a) untuk mengurangi berapa kali lambda dipanggil.
sumber
Solusi ini tidak sekuat yang lain, tetapi jika Anda seorang pemula dan hanya tahu tentang
for
loop, masih mungkin untuk menemukan indeks pertama dari suatu item sambil menghindari ValueError:sumber
Menemukan indeks item x dalam daftar L:
sumber
Karena daftar Python berbasis nol, kita dapat menggunakan fungsi built-in zip sebagai berikut:
di mana "tumpukan jerami" adalah daftar yang dimaksud dan "jarum" adalah item yang harus dicari.
(Catatan: Di sini kita beralih menggunakan i untuk mendapatkan indeks, tetapi jika kita perlu lebih fokus pada item kita dapat beralih ke j.)
sumber
Ini menjelaskan jika string juga tidak ada dalam daftar, jika tidak ada dalam daftar
location = -1
sumber
index()
Metode Python melempar kesalahan jika item tidak ditemukan. Jadi alih-alih, Anda dapat membuatnya mirip denganindexOf()
fungsi JavaScript yang kembali-1
jika item tidak ditemukan:sumber
Ada jawaban yang lebih fungsional untuk ini.
Bentuk yang lebih umum:
sumber
Scala
/ penggemar pemrograman fungsionalMari beri nama
lst
pada daftar yang Anda miliki. Orang dapat mengonversi daftarlst
ke anumpy array
. Dan, kemudian gunakan numpy.where untuk mendapatkan indeks dari item yang dipilih dalam daftar. Mengikuti adalah cara di mana Anda akan mengimplementasikannya.sumber
Bagi mereka yang berasal dari bahasa lain seperti saya, mungkin dengan loop sederhana lebih mudah untuk memahami dan menggunakannya:
Saya bersyukur untuk apa yang dilakukan oleh seorang enumerasi? . Itu membantu saya untuk mengerti.
sumber
Jika Anda akan menemukan indeks sekali maka menggunakan metode "indeks" baik-baik saja. Namun, jika Anda akan mencari data Anda lebih dari sekali maka saya sarankan menggunakan modul dua bagian . Perlu diingat bahwa menggunakan data modul dua bagian harus diurutkan. Jadi Anda mengurutkan data sekali dan kemudian Anda dapat menggunakan dua bagian. Menggunakan modul bisect pada mesin saya sekitar 20 kali lebih cepat daripada menggunakan metode indeks.
Berikut adalah contoh kode menggunakan sintaksis Python 3.8 dan di atas:
Keluaran:
sumber
Jika kinerja menjadi perhatian:
Disebutkan dalam berbagai jawaban bahwa metode
list.index(item)
metode bawaan adalah algoritma O (n). Tidak apa-apa jika Anda perlu melakukan ini sekali. Tetapi jika Anda perlu mengakses indeks elemen beberapa kali, lebih masuk akal untuk membuat kamus (O (n)) pertama dari pasangan item-indeks, dan kemudian mengakses indeks pada O (1) setiap kali Anda membutuhkan Itu.Jika Anda yakin bahwa item dalam daftar Anda tidak pernah diulang, Anda dapat dengan mudah:
Jika Anda mungkin memiliki elemen duplikat, dan perlu mengembalikan semua indeksnya:
sumber
Seperti yang ditunjukkan oleh @TerryA, banyak jawaban membahas cara menemukan satu indeks.
more_itertools
adalah perpustakaan pihak ketiga dengan alat untuk menemukan beberapa indeks dalam iterable.Diberikan
Kode
Temukan indeks dari beberapa pengamatan:
Uji beberapa item:
Lihat juga opsi lainnya dengan
more_itertools.locate
. Instal via> pip install more_itertools
.sumber
menggunakan kamus, di mana proses daftar pertama dan kemudian tambahkan indeks ke dalamnya
sumber
menurut saya
["foo", "bar", "baz"].index("bar")
itu bagus tapi itu tidak cukup! karena jika "bar" tidak ada dalam kamus,ValueError
dinaikkan . Jadi Anda dapat menggunakan fungsi ini:dan hasilnya adalah:
dan jika nama tidak ada di arr, fungsi mengembalikan -1. sebagai contoh:
sumber
l = [1, 2]; find_index(l, 3)
akan kembali-1
danl[find_index(l, 3)]
akan kembali2
. -1 adalah hal yang buruk untuk kembali, hanya kembali Tidak ada.