Listedeki bir öğenin dizinini bulma


3181

Bir liste ["foo", "bar", "baz"]ve listedeki bir öğe verildiğinde "bar", dizinini ( 1) Python'da nasıl edinebilirim ?


6
Eğer dönüyor: [1] birden çok örneği vardır durumda en düşük endeks "bar", [2] Tüm endeksleri "bar"?
Ṃųỻịgǻňạcểơửṩ

4
a) Öğenin listede olduğu garanti ediliyor mu, yoksa hata durumunu nasıl ele almalıyız? (dönüş Yok / ValueError değerini döndürür) b) Liste girişlerinin benzersiz olduğu garanti ediliyor mu ve bir eşleşmenin ilk dizinini mi yoksa tüm dizinleri mi döndürmeliyiz?
smci

Cevapları numpy entegrasyonu ile görüntüleyin, numpy dizileri Python listelerinden çok daha verimlidir. Liste kısaysa, Python listesinden bir kopyasını almak hiç sorun değil, eğer değilse, öğeleri ilk etapta numpy dizisinde saklamayı düşünmelisiniz.
Athanassios

Yanıtlar:


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

Referans: Veri Yapıları> Listeler Hakkında Daha Fazla Bilgi

Uyarılar takip

Not Bu belki soruyu cevaplamak için en temiz yolu ise o istedi olarak , indexbir oldukça zayıf bir bileşendir listAPI ve ben öfke kullanmış son kez hatırlayamıyorum. Yorumlarda bana bu cevaba yoğun bir şekilde atıfta bulunulduğu için daha eksiksiz yapılması gerektiği belirtildi. Bazı uyarılar list.indextakip ediyor. Muhtemelen başlangıçta bunun için belgelere bir göz atmaya değer:

list.index(x[, start[, end]])

Değeri x'e eşit olan ilk öğe listesinde sıfır temelli dizin döndürür . ValueErrorBöyle bir öğe yoksa bir yükseltir .

İsteğe bağlı başlangıç ve bitiş bağımsız değişkenleri dilim gösterimindeki gibi yorumlanır ve aramayı listenin belirli bir alt dizisiyle sınırlamak için kullanılır. Döndürülen dizin, başlangıç ​​bağımsız değişkeni yerine tam dizinin başlangıcına göre hesaplanır.

Liste uzunluğunda doğrusal zaman karmaşıklığı

bir index çağrı, bir eşleşme bulana kadar listenin her öğesini sırayla kontrol eder. Listeniz uzunsa ve kabaca listenin neresinde gerçekleştiğini bilmiyorsanız, bu arama bir darboğaz haline gelebilir. Bu durumda, farklı bir veri yapısı düşünmelisiniz. Maçı kabaca nerede bulacağınızı biliyorsanız indexbir ipucu verebileceğinizi unutmayın . Örneğin, bu pasajda l.index(999_999, 999_990, 1_000_000)kabaca beş büyüklük sırası düzden daha hızlıdır l.index(999_999), çünkü birincisi sadece 10 giriş aramak zorundadır, ikincisi ise bir milyon arar:

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

Yalnızca ilk eşleşmenin dizinini bağımsız değişkenine döndürür

Bir indexeşleşme bulana kadar listede arama yapmak için yapılan bir çağrı ve orada durana . Daha fazla eşleşme indeksine ihtiyacınız varsa, bir liste kavrama veya jeneratör ifadesi kullanmalısınız.

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

Eskiden kullandığım çoğu yer index , şimdi daha genelleştirilebilir oldukları için bir liste kavrama veya jeneratör ifadesi kullanıyorum. Yani index, ulaşmayı düşünüyorsanız , bu mükemmel Python özelliklerine bir göz atın.

Öğe listede yoksa atar

Bir çağrı indexbir sonuçlardan ValueErroröğesi mevcut değilse.

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

Öğe listede bulunmuyorsa,

  1. Önce şunu kontrol edin item in my_list (temiz, okunabilir yaklaşım) veya
  2. indexAramayı try/exceptyakalayan bir bloğa sarın ValueError(muhtemelen daha hızlı, en azından aranacak liste uzun olduğunda ve öğe genellikle mevcutsa).

20
index değeri "bar" olan ilk öğeyi döndürür. Listede iki kez "bar" varsa, ikinci "bar" ın anahtarını asla bulamazsınız. Belgelere bakın: docs.python.org/3/tutorial/datastructures.html
mpoletto

2
Yalnızca bir öğe (ilk) arıyorsanız index(), tamsayı listelerine göre liste kavrayışından% 90'ın biraz altında olduğunu buldum .
slybloty

Liste çok uzunsa hangi veri yapısı kullanılmalıdır?
22:36

@izhang: Öğeler yıkanabilirse ve listedeki konum önemliyse, {element -> list_index} dict gibi bazı yardımcı dizin.
Alex Coventry

898

Python'u öğrenmede gerçekten yararlı olan bir şey, interaktif yardım işlevini kullanmaktır:

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

class list(object)
 ...

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

Bu genellikle sizi aradığınız yönteme yönlendirir.


2
bpython , dokümanları interaktif bir şekilde okumanın kullanıcı dostu güzel bir yoludur.
goetzc

@davidavr evet, ama sonra yardım belgelerini kaydırmak yerine sadece google yapmak isteyen geri kalanlarımız bu güzel, merkezi, sıralı seçenek kümesine sahip olmazdı. :)
honkaboy

555

Cevapların çoğu tek bir endeksin nasıl bulunacağını açıklıyor , ancak öğe listede birden çok kez bulunuyorsa yöntemleri birden çok dizin döndürmez. Kullanım enumerate():

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

index()Fonksiyon sadece ise, ilk geçtiği döndürürenumerate() tüm oluşumları döndürür.

Bir liste olarak:

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

İşte bir başka küçük çözüm itertools.count() (numaralandırma ile hemen hemen aynı yaklaşımdır):

from itertools import izip as zip, count # izip for maximum efficiency
[i for i, j in zip(count(), ['foo', 'bar', 'baz']) if j == 'bar']

Bu, büyük listeler için kullanmaktan daha etkilidir 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

Numaralandırma benim için dizin tabanlı yöntemlerden daha iyi çalışır, çünkü 'startswith "kullanarak dizelerin dizinlerini toplamak için arıyorum ve birden çok kez toplamak gerekir. anlayamadım
Tupelo Thistlehead

3
Ellerimde, numaralandırılmış versiyon sürekli olarak biraz daha hızlı. Yukarıdaki ölçüm yayınlandığından beri bazı uygulama ayrıntıları değişmiş olabilir.
Alex Coventry

2
Bu, '
11'den

175

Tüm dizinleri almak için:

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

4
Bunun için başka bir soru daha var, '
11'e

132

index()değerin ilk dizinini döndürür !

| dizin (...)
| L.index (değer; [başlangıç; [durdur]]) -> tamsayı - değerin ilk dizinini döndür

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

2
Ve listede yoksa?
Peter Mortensen

1
Mevcut olmayan öğe ValueError'u artıracak
Nam G VU

1
Bu cevap buraya daha iyi uyacak: stackoverflow.com/questions/6294179/…
Cristik

86

Öğe listede değilse bir sorun ortaya çıkar. Bu işlev sorunu ele alır:

# 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


58

Aradığınız öğenin listede olup olmadığını kontrol etmek için bir koşul ayarlamanız gerekir

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

1
Bu, yakalamayı denememize yardımcı olur!
devssh

Ancak, karmaşıklığı iki katına çıkarabilir. Kimse kontrol etti mi?
stefanct

@stefanct Zaman karmaşıklığı hala doğrusaldır, ancak listede iki kez yinelenir.
ApproachingDarknessFish

@ApproachingDarknessFish Açıkçası kastettiğim bu. Bilgiçlikle aynı karmaşıklık sırası olsa bile , birçok kullanım durumunda iki kez yineleme ciddi bir dezavantaj olabilir, bu yüzden onu gündeme getirdim. Ve hala cevabı bilmiyoruz ...
stefanct

44

Burada önerilen tüm işlevler doğal dil davranışını yeniden oluşturur, ancak neler olup bittiğini gizler.

[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

Dil, istediğiniz şeyi yapmak için yöntemler sağlıyorsa neden istisna işlemeli bir işlev yazmalısınız?


9
3. yöntem listede iki kez yinelenir, değil mi?
Eric Duminil

Re: "Burada önerilen tüm fonksiyonlar" : Belki de yazarken, ama hala doğru olup olmadığını görmek için daha yeni cevapları kontrol etmelisiniz.
Peter Mortensen

41

Tüm dizinleri istiyorsanız, NumPy'yi kullanabilirsiniz :

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

Net, okunabilir bir çözümdür.


4
Dize listeleri, sayısal olmayan nesne listeleri vb. Hakkında ne düşünüyorsunuz?
Laryx Decidua

1
Bu yanıtı buraya göndermelisiniz: stackoverflow.com/questions/6294179/…
Cristik

1
Bu okuduğum en iyisi. numpy dizileri Python listelerinden çok daha verimlidir. Liste kısaysa, Python listesinden bir kopyasını almak hiç sorun değil, belki de değilse geliştirici öğeleri numpy dizisinde ilk etapta saklamayı düşünmelidir.
Athanassios

35

Python'da içeren bir liste verilen bir öğenin dizinini bulma

Bir liste ["foo", "bar", "baz"]ve listedeki bir öğe "bar"için, dizinini (1) Python'da almanın en temiz yolu nedir?

Elbette, ilk oluşumun dizinini döndüren dizin yöntemi var:

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

Bu yöntemle ilgili birkaç sorun var:

  • değer listede yoksa, bir ValueError
  • listede birden fazla değer varsa, yalnızca ilk değerin dizinini alırsınız

Değer yok

Değer eksikse, simgesini yakalamanız gerekir ValueError.

Bunu, aşağıdaki gibi yeniden kullanılabilir bir tanımla yapabilirsiniz:

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

Ve şu şekilde kullanın:

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

Ve bunun dezavantajı, döndürülen değerin isveya is notHiçbirinin:

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

Listede birden fazla değer

Daha fazla olay yaşarsanız, aşağıdakilerle ilgili tam bilgi alamazsınızlist.index :

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

Dizinleri anlamak için bir liste sıralayabilirsiniz:

>>> [index for index, v in enumerate(l) if v == 'bar']
[1, 3]
>>> [index for index, v in enumerate(l) if v == 'boink']
[]

Herhangi bir durumunuz yoksa, sonucun boolean kontrolü ile bunu kontrol edebilir veya sadece sonuçlar üzerinde döngü yaparsanız hiçbir şey yapamazsınız:

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

Pandalarla daha iyi veri ayıklama

Pandalarınız varsa, bu bilgileri bir Series nesnesiyle kolayca alabilirsiniz:

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

Karşılaştırma denetimi bir dizi boole döndürür:

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

Bu boole serilerini alt simge notasyonu ile seriye aktarın ve sadece eşleşen üyelere sahip olun:

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

Yalnızca dizinleri istiyorsanız, index özelliği bir tamsayı dizisi döndürür:

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

Ve onları bir listede veya grupta istiyorsanız, bunları yapıcıya iletin:

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

Evet, numaralandırma ile bir liste kavrayışı da kullanabilirsiniz, ancak bu kadar zarif değil, bence - C'de yazılı yerleşik kodun üstesinden gelmek yerine Python'da eşitlik testleri yapıyorsunuz:

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

Bu bir XY sorunu mu?

XY problemi, gerçek probleminiz yerine denediğiniz çözümü soruyor.

Neden bir listede bir öğe verilen dizine ihtiyacınız olduğunu düşünüyorsunuz?

Değeri zaten biliyorsanız, neden bir listede olduğunu umursuyorsunuz?

Değer orada değilse, yakalamak ValueErroroldukça ayrıntılı - ve bundan kaçınmayı tercih ederim.

Genellikle liste üzerinde yineleme yapıyorum, bu yüzden genellikle numaralandırma ile dizin almak, herhangi bir ilginç bilgilere bir işaretçi tutacağım .

Verileri munging ediyorsanız, muhtemelen gösterdiğim saf Python geçici çözümlerinden çok daha zarif araçlara sahip pandalar kullanmalısınız.

İhtiyacım olduğunu hatırlamıyorum list.index, kendim. Ancak, Python standart kütüphanesine baktım ve bunun için bazı mükemmel kullanımlar görüyorum.

idlelibGUI ve metin ayrıştırma için bunun birçok kullanımı vardır .

keywordModül kullanır bunu otomatik olarak metaprogramlama aracılığı anahtar kelime listesini yenilemek için modülde açıklama işaretleri bulmak için.

Lib / mailbox.py'de sıralı bir eşleme gibi kullanıyor gibi görünüyor:

key_list[key_list.index(old)] = new

ve

del key_list[key_list.index(key)]

Lib / http / cookiejar.py'de, gelecek ay almak için kullanılıyor gibi görünüyor:

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

Bir öğeye kadar bir dilim almak için distutils'e benzer Lib / tarfile.py'de:

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

Lib / pickletools.py'de:

numtopop = before.index(markobject)

Bu kullanımların ortak olarak göründüğü şey, kısıtlı boyutlar listelerinde çalışıyor gibi görünmeleridir (O ​​(n) arama süresi nedeniyle önemlidir list.index ve çoğunlukla ayrıştırmada (ve Boşta durumunda UI) kullanıldıklarıdır.

Bunun için kullanım durumları olsa da, oldukça nadirdir. Kendinizi bu cevabı ararken bulursanız, kendinize yaptığınız şeyin kullanım durumunuz için dil tarafından sağlanan araçların en doğrudan kullanımı olup olmadığını sorun.



21

Bir listedeki bir veya daha fazla (özdeş) öğenin tüm oluşumlarını ve konumunu alma

Enumerate (alist) ile, x öğesi aradığınız şeye eşit olduğunda listenin dizini olan ilk öğeyi (n) saklayabilirsiniz.

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

Fonksiyonumuzu findindex yapalım

Bu işlev, öğeyi ve listeyi bağımsız değişken olarak alır ve öğenin daha önce gördüğümüz gibi listedeki konumunu döndürür.

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

Çıktı


[1, 3, 5, 7]

Basit

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

Çıktı:

0
4

1
Bu yanıtı buraya göndermelisiniz: stackoverflow.com/questions/6294179/…
Cristik

16

Sadece gidebilirsin

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

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


15

Ve şimdi tamamen farklı bir şey...

... dizini almadan önce öğenin varlığını onaylamak gibi. Bu yaklaşımla ilgili güzel olan şey, fonksiyonun her zaman bir indeks listesi döndürmesidir - boş bir liste olsa bile. Dizelerle de çalışır.

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

Etkileşimli bir python penceresine yapıştırıldığında:

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

Güncelleme

Head-down python geliştirmenin bir yıl sonra, orijinal cevabımdan biraz utanıyorum, bu yüzden kaydı düz ayarlamak için kesinlikle yukarıdaki kodu kullanabilirsiniz; ancak, aynı davranışı elde etmenin çok daha deyimsel yolu, enumerate () işlevinin yanı sıra liste kavrayışı kullanmak olacaktır.

Bunun gibi bir şey:

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

Bu, etkileşimli bir python penceresine yapıştırıldığında şunları sağlar:

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

Ve şimdi, bu soruyu ve bütün cevapları inceledikten sonra, bu tam olarak ne olduğunu fark FMC onun önerilen önceki yanıt . Bu soruyu ilk başta cevapladığım zaman, bu cevabı bile görmedim , çünkü anlamadım. Umarım biraz daha ayrıntılı örneğimin anlamaya yardımcı olacağını umarım.

Kod tek satır yukarıda hala varsa yok size mantıklı, ben çok size Google'ın piton liste anlama 'tavsiye ve yakından tanımak için birkaç dakika sürebilir. Kod geliştirmek için Python'u kullanmanın bir zevk olmasını sağlayan birçok güçlü özellikten sadece biri.


12

FMc ve user7177'nin cevabındaki bir varyant, herhangi bir giriş için tüm endeksleri geri gönderebilecek bir dikte verecektir:

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

Tek bir giriş için tüm indeksleri almak için bunu tek bir astar olarak da kullanabilirsiniz. Verimlilik için hiçbir garanti yok, ancak lambda'nın kaç kez çağrıldığını azaltmak için set (a) kullandım.


1
Bu yanıtı buraya göndermelisiniz: stackoverflow.com/questions/6294179/…
Cristik

10

Bu çözüm diğerleri kadar güçlü değildir, ancak yeni başlayan biriyseniz ve yalnızca fordöngüler hakkında bilgi sahibi iseniz , ValueError'dan kaçınırken bir öğenin ilk dizinini bulmak hala mümkündür:

def find_element(p,t):
    i = 0
    for e in p:
        if e == t:
            return i
        else:
            i +=1
    return -1

9

L listesindeki x öğesinin dizinini bulma:

idx = L.index(x) if (x in L) else -1

4
Bu, diziyi iki kez yineler, bu nedenle büyük diziler için performans sorunlarına neden olabilir.
Cristik

Katılıyorum. Listeler oldukça uzunsa, başka bir şey ararım. Ancak küçük ve orta ölçekli listeler için büyük bir anlaşma olmamalıdır.
Ketan

5

Python listeleri sıfır tabanlı olduğundan, zip yerleşik işlevini aşağıdaki gibi kullanabiliriz:

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

burada "samanlık" söz konusu listedir ve "iğne" aranacak öğedir.

(Not: Burada, dizinleri almak için i'yi tekrarlıyoruz, ancak öğelere odaklanmak yerine j'ye geçebiliriz.)


3
[i for i, j == 'iğne' ise numaralandırmada (samanlık) j] daha kompakt ve okunaklı olduğunu düşünüyorum.
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)

Bu, dize de listede değilse, listede yoksa location = -1


4

index()Öğe bulunamadığı takdirde Python yöntemi bir hata atar. Bunun yerine , öğenin bulunmaması durumunda indexOf()dönen JavaScript işlevine benzer hale getirebilirsiniz -1:

try:
    index = array.index('search_keyword')
except ValueError:
    index = -1

5
ancak, JavaScript garip sonuçların hatalardan daha iyi olduğu felsefesine sahiptir, bu nedenle -1 döndürmek mantıklıdır, ancak Python'da, -1 listenin sonundan bir öğe döndürdüğü için hatayı izlemek zor olabilir.
Sapphire_Brick

3

Bunun daha işlevsel bir cevabı var.

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

Daha genel bir form:

def get_index_of(lst, element):
    return list(map(lambda x: x[0],\
       (list(filter(lambda x: x[1]==element, enumerate(lst))))))

1
Bu cevap Scala/ fonksiyonel programlama meraklıları için evde hissediyor
y2k-shubham

3

Sahip lstolduğunuz listeye bir isim verelim . Listeyi lstbir numpy array. Ve sonra listede seçilen öğenin dizinini almak için numpy.where komutunu kullanın. Bunu nasıl uygulayacağınız aşağıda açıklanmıştır.

import numpy as np

lst = ["foo", "bar", "baz"]  #lst: : 'list' data type
print np.where( np.array(lst) == 'bar')[0][0]

>>> 1

2

Benim gibi başka bir dilden gelenler için, belki de basit bir döngü ile anlamak ve kullanmak daha kolaydır:

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

Ben şükrediyorum Peki numaralandırma tam olarak ne yapıyor? . Bu anlamama yardımcı oldu.


2

Bir kez bir dizin bulacaksanız "index" yöntemini kullanmak iyidir. Ancak, verilerinizi bir kereden fazla arayacaksanız bisect modülünü kullanmanızı öneririm . İki modül modülünün kullanımının sıralanması gerektiğini unutmayın. Böylece verileri bir kez sıralarsınız ve sonra bisect'i kullanabilirsiniz. Kullanılması kenarortay benim makinede modülü hızlı indeks yöntemi kullanılarak 20 katına hakkındadır.

Python 3.8 ve üstü sözdizimini kullanan bir kod örneği:

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

Çıktı:

t1=0.0400, t2=0.0020, diffs t1/t2=19.60

1

Performans endişe kaynağı ise:

Çok sayıda cevapta, yerleşik yöntemin list.index(item) yönteminin bir O (n) algoritması olduğu belirtilmektedir. Bunu bir kez yapmanız gerekiyorsa sorun değil. Ancak, öğelerin dizinlerine birkaç kez erişmeniz gerekiyorsa, önce öğe dizini çiftlerinin bir sözlüğünü (O (n)) oluşturmak ve ardından her ihtiyacınız olduğunda dizine O (1) 'den erişmek daha mantıklıdır. o.

Listenizdeki öğelerin asla tekrarlanmadığından eminseniz, şunları yapabilirsiniz:

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.

Yinelenen öğeleriniz varsa ve tüm dizinlerini döndürmeniz gerekiyorsa:

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]

1

@TerryA tarafından belirtildiği gibi, birçok cevap bir endeksin nasıl bulunacağını tartışır .

more_itertools, bir yinelenebilir alan içindeki birden çok dizini bulmak için araçlar içeren üçüncü taraf bir kütüphanedir .

verilmiş

import more_itertools as mit


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

kod

Birden fazla gözlemin indekslerini bulun:

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

Birden fazla öğeyi test et:

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

Ayrıca ile daha fazla seçeneğe bakın more_itertools.locate. Yoluyla yükleyin > pip install more_itertools.


0

sözlük kullanarak, önce listeyi işleyin ve ardından dizini buna ekleyin

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]

-1

bence ["foo", "bar", "baz"].index("bar")iyi ama yeterli değil çünkü "bar" sözlükte değilse, ValueErroryükseltilmiş.Bu yüzden bu işlevi kullanabilirsiniz:

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

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

ve sonuç:

1

ve ad arr değerinde değilse, işlev -1 döndürür. örneğin:

yazdır (find_index (["foo", "bar", "baz"], "fooo"))

-1


1
Bunu kullanmayın çünkü l = [1, 2]; find_index(l, 3)dönecekti -1ve l[find_index(l, 3)]dönecekti 2. -1 geri dönmek için kötü bir şey, sadece geri dönmek Yok.
Daniel Stracaboško

-1 istediğiniz her şeyi döndürebileceğiniz bir sözleşmedir Ama programlarınızda daha azını kullanmaya çalışın çünkü programınızın android ve PHP web siteleri gibi diğer programlarla iletişiminde Yok veya Null, örneğin JSON'da null döndürebilirsiniz. ve web sitesi telefonu uygulamanız kapanır veya Hata 500 (dahili sunucu hatası) döndürür.
NaabNuts
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.