Menemukan indeks suatu item dalam daftar

3183

Diberikan daftar ["foo", "bar", "baz"]dan item dalam daftar "bar", bagaimana cara mendapatkan indeksnya ( 1) dengan Python?

Eugene M
sumber
6
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.
Athanassios

Jawaban:

4488
>>> ["foo", "bar", "baz"].index("bar")
1

Referensi: Struktur Data> Lebih Lanjut tentang Daftar

Peringatan diikuti

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:

>>> import timeit
>>> timeit.timeit('l.index(999_999)', setup='l = list(range(0, 1_000_000))', number=1000)
9.356267921015387
>>> timeit.timeit('l.index(999_999, 999_990, 1_000_000)', setup='l = list(range(0, 1_000_000))', number=1000)
0.0004404920036904514

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: 2 is not in list

Jika item itu mungkin tidak ada dalam daftar, Anda juga harus

  1. Periksa terlebih dahulu dengan item in my_list(pendekatan bersih, dapat dibaca), atau
  2. Bungkus indexpanggilan dalam try/exceptblok yang menangkap ValueError(mungkin lebih cepat, setidaknya ketika daftar untuk pencarian panjang, dan item biasanya ada.)
Alex Coventry
sumber
20
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.

davidavr
sumber
2
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
TerryA
sumber
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.
Alex Coventry
2
Ini sudah dijawab sejak '11: stackoverflow.com/questions/6294179/…
Cristik
175

Untuk mendapatkan semua indeks:

indexes = [i for i,x in enumerate(xs) if x == 'foo']
FMc
sumber
4
Sudah ada pertanyaan lain untuk ini, ditambahkan pada '11: stackoverflow.com/questions/6294179/…
Cristik
132

index()mengembalikan pertama indeks nilai!

| indeks (...)
| L.index (nilai, [mulai, [berhenti]]) -> integer - mengembalikan indeks nilai pertama

def all_indices(value, qlist):
    indices = []
    idx = -1
    while True:
        try:
            idx = qlist.index(value, idx+1)
            indices.append(idx)
        except ValueError:
            break
    return indices

all_indices("foo", ["foo","bar","baz","foo"])
HongboZhu
sumber
2
Dan jika tidak ada dalam daftar?
Peter Mortensen
1
Item yang tidak ada akan meningkatkan ValueError
Nam G VU
1
Jawaban ini akan lebih cocok di sini: stackoverflow.com/questions/6294179/…
Cristik
86

Masalah akan muncul jika elemen tidak ada dalam daftar. Fungsi ini menangani masalah:

# if element is found it returns index of element else returns None

def find_element_in_list(element, list_element):
    try:
        index_element = list_element.index(element)
        return index_element
    except ValueError:
        return None
tanzil
sumber
79
a = ["foo","bar","baz",'bar','any','much']

indexes = [index for index in range(len(a)) if a[index] == 'bar']
Savinson
sumber
1
Jawaban ini seharusnya lebih baik diposting di sini: stackoverflow.com/questions/6294179/…
Cristik
58

Anda harus menetapkan kondisi untuk memeriksa apakah elemen yang Anda cari ada dalam daftar

if 'your_element' in mylist:
    print mylist.index('your_element')
else:
    print None
pengguna3670684
sumber
1
Ini membantu kita untuk menghindari coba tangkap!
devssh
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 else None    # get the first index and fail quietly

Mengapa menulis fungsi dengan penanganan pengecualian jika bahasa tersebut menyediakan metode untuk melakukan apa yang Anda inginkan?

Graham Giller
sumber
9
Metode ke-3 berulang dua kali dari daftar, kan?
Eric Duminil
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 :

import numpy as np

array = [1, 2, 1, 3, 4, 5, 1]
item = 1
np_array = np.array(array)
item_index = np.where(np_array==item)
print item_index
# Out: (array([0, 2, 6], dtype=int64),)

Ini jelas, solusi yang mudah dibaca.

rbrisuda
sumber
4
Bagaimana dengan daftar string, daftar objek non-numerik, dll ...?
Laryx Decidua
1
Jawaban ini lebih baik diposting di sini: stackoverflow.com/questions/6294179/…
Cristik
1
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:

def index(a_list, value):
    try:
        return a_list.index(value)
    except ValueError:
        return None

Dan gunakan seperti ini:

>>> print(index(l, 'quux'))
None
>>> print(index(l, 'bar'))
1

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 is not None:
    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'
0    False
1     True
2    False
3     True
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:

>>> series[series == 'bar'].index
Int64Index([1, 3], dtype='int64')

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]

Apakah ini masalah XY ?

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.

Aaron Hall
sumber
22

Semua indeks dengan zipfungsi:

get_indexes = lambda x, xs: [i for (y, i) in zip(xs, range(len(xs))) if x == y]

print get_indexes(2, [1, 2, 3, 4, 5, 6, 3, 2, 3, 2])
print get_indexes('f', 'xsfhhttytffsafweef')
Arnaldo P. Figueira Figueira
sumber
1
Jawaban ini lebih baik diposting di sini: stackoverflow.com/questions/6294179/…
Cristik
21

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)

Keluaran:

0
4
Giovanni G. PY
sumber
1
Jawaban ini seharusnya lebih baik diposting di sini: stackoverflow.com/questions/6294179/…
Cristik
16

Cukup Anda bisa pergi dengan

a = [['hand', 'head'], ['phone', 'wallet'], ['lost', 'stock']]
b = ['phone', 'lost']

res = [[x[0] for x in a].index(y) for y in b]
Kiriloff
sumber
16

Pilihan lain

>>> 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]
>>> 
Perangkat Lunak Mathitis2
sumber
1
Jawaban ini lebih baik diposting di sini: stackoverflow.com/questions/6294179/…
Cristik
15

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 = 0
    while val in l[last:]:
            i = l[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)
print indices(l,'bat')
print indices('abcdaababb','a')

Ketika disisipkan ke jendela python interaktif:

Python 2.7.6 (v2.7.6:3a1db0d2747e, Nov 10 2013, 00:42:54) 
[GCC 4.2.1 (Apple Inc. 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:

Python 2.7.14 |Anaconda, Inc.| (default, Dec  7 2017, 11:07:58) 
[GCC 4.2.1 Compatible Clang 4.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.

MrWificent
sumber
12

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.

bvanlew
sumber
1
Jawaban ini seharusnya lebih baik diposting di sini: stackoverflow.com/questions/6294179/…
Cristik
10

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 = 0
    for e in p:
        if e == t:
            return i
        else:
            i +=1
    return -1
dylankb
sumber
9

Menemukan indeks item x dalam daftar L:

idx = L.index(x) if (x in L) else -1
Ketan
sumber
4
Ini mengulangi array dua kali, sehingga bisa mengakibatkan masalah kinerja untuk array besar.
Cristik
Setuju. Jika daftarnya sangat panjang, saya akan mencari yang lain. Seharusnya tidak menjadi masalah besar untuk daftar ukuran kecil hingga menengah.
Ketan
5

Karena daftar Python berbasis nol, kita dapat menggunakan fungsi built-in zip sebagai berikut:

>>> [i for i,j in zip(range(len(haystack)), haystack) if j == 'needle' ]

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

jihed gasmi
sumber
3
[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=-1
print (location)

Ini menjelaskan jika string juga tidak ada dalam daftar, jika tidak ada dalam daftar location = -1

Coder123
sumber
4

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')
except ValueError:
    index = -1
Hamed Baatour
sumber
5
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.
Sapphire_Brick
3

Ada jawaban yang lebih fungsional untuk ini.

list(filter(lambda x: x[1]=="bar",enumerate(["foo", "bar", "baz", "bar", "baz", "bar", "a", "b", "c"])))

Bentuk yang lebih umum:

def get_index_of(lst, element):
    return list(map(lambda x: x[0],\
       (list(filter(lambda x: x[1]==element, enumerate(lst))))))
Ankit Gupta
sumber
1
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 type
print np.where( np.array(lst) == 'bar')[0][0]

>>> 1
Siddharth Satpathy
sumber
2

Bagi mereka yang berasal dari bahasa lain seperti saya, mungkin dengan loop sederhana lebih mudah untuk memahami dan menggunakannya:

mylist = ["foo", "bar", "baz", "bar"]
newlist = enumerate(mylist)
for index, item in newlist:
  if item == "bar":
    print(index, item)

Saya bersyukur untuk apa yang dilakukan oleh seorang enumerasi? . Itu membantu saya untuk mengerti.

mpoletto
sumber
2

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

Keluaran:

t1=0.0400, t2=0.0020, diffs t1/t2=19.60
Vlad Bezden
sumber
1

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:

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]
FatihAkici
sumber
1

Seperti yang ditunjukkan oleh @TerryA, banyak jawaban membahas cara menemukan satu indeks.

more_itertoolsadalah perpustakaan pihak ketiga dengan alat untuk menemukan beberapa indeks dalam iterable.

Diberikan

import more_itertools as mit


iterable = ["foo", "bar", "baz", "ham", "foo", "bar", "baz"]

Kode

Temukan indeks dari beberapa pengamatan:

list(mit.locate(iterable, lambda x: x == "bar"))
# [1, 5]

Uji beberapa item:

list(mit.locate(iterable, lambda x: x in {"bar", "ham"}))
# [1, 3, 5]

Lihat juga opsi lainnya dengan more_itertools.locate. Instal via > pip install more_itertools.

pylang
sumber
0

menggunakan kamus, di mana proses daftar pertama dan kemudian tambahkan indeks ke dalamnya

from collections import defaultdict

index_dict = defaultdict(list)    
word_list =  ['foo','bar','baz','bar','any', 'foo', 'much']

for word_index in range(len(word_list)) :
    index_dict[word_list[word_index]].append(word_index)

word_index_to_find = 'foo'       
print(index_dict[word_index_to_find])

# output :  [0, 5]
sahasrara62
sumber
-1

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:

def find_index(arr, name):
    try:
        return arr.index(name)
    except ValueError:
        return -1

if __name__ == '__main__':
    print(find_index(["foo", "bar", "baz"], "bar"))

dan hasilnya adalah:

1

dan jika nama tidak ada di arr, fungsi mengembalikan -1. sebagai contoh:

cetak (find_index (["foo", "bar", "baz"], "fooo"))

-1

NaabNuts
sumber
1
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).
NaabNuts