Mencari indeks dari item diberikan daftar yang berisi hal di Python

Untuk daftar ["anu", "bar", "baz"] dan item dalam daftar "bar", bagaimana saya mendapatkan indeks (1) dalam Python?

Mengomentari pertanyaan (2)
Larutan
>>> ["foo", "bar", "baz"].index("bar")
1

Referensi: Struktur Data > Lebih pada List

Peringatan mengikuti

Perhatikan bahwa sementara ini mungkin terbersih cara untuk menjawab pertanyaan sewaktu diminta, index adalah agak lemah komponen dari daftar API, dan aku bisa't ingat kapan terakhir kali aku menggunakannya dalam kemarahan. It's telah menunjukkan kepada saya di komentar bahwa karena jawaban ini lebih berat dirujuk, harus dibuat lebih lengkap. Beberapa peringatan tentang daftar.index ikuti. Hal ini mungkin layak awalnya mengambil melihat docstring untuk itu:

>>> print(list.index.__doc__)
L.index(value, [start, [stop]]) -> integer -- return first index of value.
Raises ValueError if the value is not present.

Waktu linier-kompleksitas dalam daftar panjang

Sebuah index panggilan pemeriksaan setiap elemen dari daftar dalam urutan, sampai menemukan yang cocok. Jika daftar anda lebih lama, dan anda don't tahu kira-kira 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 untuk menemukan pertandingan, anda dapat memberikan index petunjuk. Misalnya, dalam cuplikan ini, l.index(999_999, 999_990, 1_000_000) kira-kira lima kali lipat lebih cepat daripada lurus l.index(999_999), karena mantan hanya untuk mencari 10 entri, sedangkan yang kedua mencari 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 dari pertandingan pertama untuk argumen

Panggilan untuk index pencarian melalui daftar di urutan sampai menemukan yang cocok, dan berhenti di sana. Jika anda berharap untuk kebutuhan indeks lebih banyak pertandingan, anda harus menggunakan daftar pemahaman, atau generator ekspresi.

>>> [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 daftar pemahaman atau generator ekspresi karena mereka're lebih generalizable. Jadi jika anda're mempertimbangkan untuk mencapai index, lihatlah ini sangat baik python fitur.

Melempar jika elemen tidak ada dalam daftar

Panggilan untuk index hasil ValueError jika item's tidak hadir.

>>> [1, 1].index(2)
Traceback (most recent call last):
  File "", line 1, in 
ValueError: 2 is not in list

Jika barang yang mungkin tidak ada dalam daftar, anda harus baik

  1. Periksa dulu dengan item di my_list (bersih, mudah dibaca pendekatan), atau
  2. Bungkus index memanggil mencoba/kecuali blok yang menangkap ValueError (mungkin lebih cepat, setidaknya ketika daftar untuk pencarian lebih lama, dan item ini biasanya hadir.)
Komentar (2)

Satu hal yang benar-benar membantu dalam belajar Python adalah dengan menggunakan bantuan interaktif fungsi:

>>> help(["foo", "bar", "baz"])
Help on list object:

class list(object)
 ...

 |
 |  index(...)
 |      L.index(value, [start, [stop]]) -> integer -- return first index of value
 |

yang sering akan menyebabkan anda untuk metode yang anda cari.

Komentar (1)

Mayoritas jawaban menjelaskan bagaimana untuk menemukan indeks tunggal, tetapi metode mereka tidak kembali beberapa indeks jika item dalam daftar beberapa kali. Gunakan menghitung():

for i, j in enumerate(['foo', 'bar', 'baz']):
    if j == 'bar':
        print(i)

Index() fungsi hanya kembali kejadian pertama, sedangkan menghitung() mengembalikan semua kejadian.

Sebagai daftar pemahaman:

[i for i, j in enumerate(['foo', 'bar', 'baz']) if j == 'bar']

Berikut ini's juga kecil lain larutan dengan itertools.count() (yang cukup banyak pendekatan yang sama seperti menghitung):

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 yang lebih besar daftar dari menggunakan menghitung():

$ 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
Komentar (3)

Untuk mendapatkan semua indeks:

indexes = [i for i,x in enumerate(xs) if x == 'foo']
Komentar (1)

index() mengembalikan pertama indeks nilai!

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

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"])
Komentar (3)

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

# 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
Komentar (0)
a = ["foo","bar","baz",'bar','any','much']

indexes = [index for index in range(len(a)) if a[index] == 'bar']
Komentar (1)

Anda harus menetapkan kondisi untuk memeriksa apakah elemen anda'kembali mencari di daftar

if 'your_element' in mylist:
    print mylist.index('your_element')
else:
    print None
Komentar (2)

Semua fungsi yang diusulkan di sini mereproduksi melekat bahasa perilaku tetapi tidak jelas apa yang's 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 pengecualian penanganan jika bahasa yang menyediakan metode untuk melakukan apa yang anda inginkan itu sendiri?

Komentar (2)

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

Hal ini jelas, mudah dibaca solusi.

Komentar (2)

Mencari indeks dari item diberikan daftar yang berisi hal di Python

Untuk daftar ["anu", "bar", "baz"] dan item dalam daftar "bar", apa's terbersih cara untuk mendapatkan indeks (1) dalam Python?

Nah, yakin, ada's metode indeks, yang mengembalikan indeks dari kemunculan pertama:

>>> l = ["foo", "bar", "baz"]
>>> l.index('bar')
1

Ada beberapa masalah dengan metode ini:

  • jika nilai isn't dalam daftar, anda'll mendapatkan ValueError
  • jika lebih dari satu nilai dalam daftar, anda hanya mendapatkan indeks untuk pertama

Tidak ada nilai-nilai

Jika nilai bisa hilang, anda perlu untuk menangkap ValueError.

Anda dapat melakukannya dengan reusable definisi seperti ini:

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

Dan menggunakannya seperti ini:

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

Dan kelemahan dari ini adalah bahwa anda mungkin akan memiliki untuk memeriksa jika nilai yang dikembalikan adalah atau tidak Tidak ada:

result = index(a_list, value)
if result is not None:
    do_something(result)

Lebih dari satu nilai dalam daftar

Jika anda bisa memiliki lebih banyak kejadian, anda'll tidak dapatkan informasi yang lengkap dengan daftar.index:

>>> l.append('bar')
>>> l
['foo', 'bar', 'baz', 'bar']
>>> l.index('bar')              # nothing at index 3?
1

Anda mungkin menghitung ke 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 memeriksa bahwa dengan boolean cek hasil, atau hanya melakukan apa-apa jika anda loop atas hasil:

indexes = [index for index, v in enumerate(l) if v == 'boink']
for index in indexes:
    do_something(index)

Baik data munging dengan panda

Jika anda memiliki panda, anda dapat dengan mudah mendapatkan informasi ini dengan Serangkaian objek:

>>> import pandas as pd
>>> series = pd.Series(l)
>>> series
0    foo
1    bar
2    baz
3    bar
dtype: object

Perbandingan check akan kembali serangkaian boolean:

>>> series == 'bar'
0    False
1     True
2    False
3     True
dtype: bool

Melewati serangkaian boolean untuk seri melalui subskrip notasi, dan anda mendapatkan hanya yang cocok anggota:

>>> series[series == 'bar']
1    bar
3    bar
dtype: object

Jika anda ingin hanya indeks, indeks atribut kembali serangkaian bilangan bulat:

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

Dan jika anda ingin mereka dalam daftar atau tuple, hanya melewati mereka untuk konstruktor:

>>> list(series[series == 'bar'].index)
[1, 3]

Ya, anda bisa menggunakan daftar pemahaman dengan menghitung juga, tapi yang's hanya tidak elegan, dalam pendapat saya - anda'kembali melakukan tes untuk kesetaraan dalam Python, bukannya membiarkan builtin kode yang ditulis dalam C mengatasinya:

>>> [i for i, value in enumerate(l) if value == 'bar']
[1, 3]

Ini adalah sebuah XY masalah?

XY masalah bertanya tentang anda mencoba solusi dan bukan masalah yang sebenarnya.

Mengapa anda pikir anda butuhkan indeks diberikan sebuah elemen dalam daftar?

Jika anda sudah tahu nilai, mengapa kau peduli di mana itu adalah di daftar?

Jika nilai isn't ada, mengejar ValueError agak verbose - dan aku lebih memilih untuk menghindari itu.

I'm biasanya iterasi daftar lagian, jadi saya'll biasanya menyimpan pointer ke setiap informasi yang menarik, mendapatkan indeks dengan menghitung.

Jika anda're munging data, anda mungkin harus menggunakan panda - yang telah jauh lebih elegan alat-alat dari Python murni workarounds I've ditampilkan.

Saya tidak ingat membutuhkan daftar.indeks, diriku sendiri. Namun, saya telah melihat melalui Python library standar, dan saya melihat beberapa menggunakan untuk itu.

Ada banyak, banyak kegunaan untuk itu dalam idlelib, untuk GUI dan teks parsing.

Kata kunci modul menggunakannya untuk menemukan komentar penanda dalam modul untuk secara otomatis regenerasi daftar kata kunci di dalamnya melalui metaprogramming.

Di Lib/mailbox.py tampaknya akan menggunakan itu seperti yang diperintahkan pemetaan:

key_list[key_list.index(old)] = new

dan

del key_list[key_list.index(key)]

Di Lib/http/cookiejar.py, tampaknya dapat digunakan untuk mendapatkan bulan berikutnya:

mon = MONTHS_LOWER.index(mon.lower())+1

Di Lib/tarfile.py mirip dengan distutils untuk mendapatkan sepotong up untuk item:

members = members[:members.index(tarinfo)]

Di Lib/pickletools.py:

numtopop = before.index(markobject)

Apa penggunaan ini tampaknya memiliki kesamaan adalah bahwa mereka tampaknya beroperasi pada daftar dibatasi ukuran (penting karena O(n) waktu pencarian untuk daftar.index), dan mereka're sebagian besar digunakan dalam parsing (dan UI dalam kasus Idle).

Sementara ada penggunaan-kasus untuk itu, mereka cukup jarang. Jika anda menemukan diri anda mencari jawaban ini, tanyakan pada diri anda jika apa yang anda're lakukan adalah yang paling langsung penggunaan alat-alat yang disediakan oleh bahasa untuk kasus penggunaan anda.

Komentar (0)

Semua indeks dengan zip fungsi:

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')
Komentar (1)

Mendapatkan semua kejadian dan posisi satu atau lebih (identik) item dalam daftar

Dengan menghitung(alist) anda dapat menyimpan elemen pertama (n) yang merupakan indeks dari daftar ketika unsur x sama dengan apa yang anda mencari.

>>> alist = ['foo', 'spam', 'egg', 'foo']
>>> foo_indexes = [n for n,x in enumerate(alist) if x=='foo']
>>> foo_indexes
[0, 3]
>>>

Let's membuat fungsi kita findindex

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

Output


[1, 3, 5, 7]

Sederhana

for n, i in enumerate([1, 2, 3, 4, 1]):
    if i == 1:
        print(n)

Output:

0
4
Komentar (1)

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]
>>> 
Komentar (1)

Hanya anda dapat 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]
Komentar (0)

Dan sekarang untuk sesuatu yang sama sekali berbeda...

... seperti mengkonfirmasikan keberadaan item sebelum mendapatkan indeks. Hal yang baik tentang pendekatan ini adalah fungsi yang selalu menampilkan daftar indeks-bahkan jika itu adalah daftar kosong. 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 interaktif python jendela:

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]
>>> 

Update

Setelah satu tahun dari kepala-down python pengembangan, aku'm sedikit malu dengan asli saya menjawab, sehingga untuk mengatur catatan lurus, salah satu pasti bisa menggunakan kode di atas; namun, banyak lebih idiomatik cara untuk mendapatkan perilaku yang sama akan menggunakan daftar pemahaman, bersama dengan menghitung() fungsi.

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 interaktif python jendela hasil:

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 ini adalah apa yang FMc yang disarankan dalam nya jawaban sebelumnya. Pada saat saya awalnya menjawab pertanyaan ini, saya didn't bahkan melihat ** yang menjawab, karena saya tidak't memahaminya. Saya berharap bahwa saya agak lebih verbose contoh akan membantu pemahaman.

Jika satu baris kode di atas masih doesn't masuk akal untuk anda, saya sangat menyarankan anda Google 'python daftar pemahaman' dan mengambil beberapa menit untuk membiasakan diri. It's hanya salah satu dari banyak fitur canggih yang membuatnya sukacita untuk menggunakan Python untuk mengembangkan kode.

Komentar (0)

Varian pada jawaban dari FMc dan user7177 akan memberikan dict yang dapat mengembalikan semua indeks untuk setiap entri:

>>> 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 salah satu kapal untuk mendapatkan semua indeks untuk single entry. Tidak ada jaminan untuk efisiensi, meskipun saya tidak menggunakan set(a) untuk mengurangi jumlah kali lambda disebut.

Komentar (1)

Solusi ini tidak sekuat orang lain, tetapi jika anda're pemula dan hanya tahu tentang `untuk'loops itu's masih mungkin untuk menemukan pertama indeks dari 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
Komentar (0)

Mencari indeks dari item x dalam daftar L:

idx = L.index(x) if (x in L) else -1
Komentar (2)
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 menyumbang jika string tidak ada dalam daftar juga, jika isn't dalam daftar maka lokasi = -1

Komentar (0)