index()yalnızca listedeki bir öğenin ilk oluşumunu verecektir. Bir listedeki tüm indeksleri döndüren düzgün bir hile var mı?
index()yalnızca listedeki bir öğenin ilk oluşumunu verecektir. Bir listedeki tüm indeksleri döndüren düzgün bir hile var mı?
Yanıtlar:
Bir liste kavrayışı kullanabilirsiniz:
indices = [i for i, x in enumerate(my_list) if x == "whatever"]
enumerate2.3'te ortaya çıktı. Yani evet, Python'unuz eskiyse kullanın filter().
print([i for i, x in enumerate([[1,1],[0,1]]) if x == 1])döner . [][[0, 1], [0, 0], [1, 1]]
(a == 1).nonzero()NumPy dizisi gibi şeyler yapmanıza izin veren NumPy'yi kullanmayı düşünmelisiniz a.
Doğrudan listeler için bir çözüm olmasa da, numpybu tür şeyler için gerçekten parlıyor:
import numpy as np
values = np.array([1,2,3,1,2,4,5,6,3,2,1])
searchval = 3
ii = np.where(values == searchval)[0]
İadeler:
ii ==>array([2, 8])
Bu, diğer bazı çözümlere kıyasla çok sayıda öğeye sahip listeler (diziler) için daha hızlı olabilir.
[0]Çünkü ihtiyaç duyulan wheregetiriler bir demet(array([2, 8], dtype=int64),)
all_id_resp_addressolmalıdır np.arraydeğil list.
listve straçıkçası geçtin Falseiçin np.where. np.arrayİkram etmekle kıyaslandığında . bir dizi boolean değer elde edersiniz. Sonra o dizinin np.wheretüm Truedeğerlerinin konumlarını bulur .
Kullanarak bir çözüm list.index:
def indices(lst, element):
result = []
offset = -1
while True:
try:
offset = lst.index(element, offset+1)
except ValueError:
return result
result.append(offset)
enumerateBüyük listeler için liste kavrayışından çok daha hızlıdır . Bu daha yavaş daha da numpyçözelti halinde önceden dizi başka türlü hızlı kazanç daha ağır basar dönüştürme maliyeti (100, 1000 ve 10000 elemanları tamsayı listelerinde test edilmiştir).
NOT: Chris_Rands'ın yorumuna dayanan bir uyarı notu: sonuçlar yeterince seyrek ise, ancak liste aranan öğenin birçok örneğine sahipse (listenin ~% 15'inden fazlası) bu çözüm liste kavramadan daha hızlıdır , 1000 tamsayı içeren bir testte) liste kavraması daha hızlıdır.
timeit.timeitrastgele oluşturulmuş listelerle kullandım. Yine de bu önemli bir nokta ve sanırım bu yüzden sordunuz. O zaman bana gelmedi, ancak hız kazanımları sadece sonuçlar yeterince seyrek ise doğrudur. Sadece aranacak unsurla dolu bir listeyle test ettim ve liste kavrayışından çok daha yavaş.
more_itertools.locate bir koşulu karşılayan tüm öğeler için endeksler bulur.
from more_itertools import locate
list(locate([0, 1, 1, 0, 1, 0, 0]))
# [1, 2, 4]
list(locate(['a', 'b', 'c', 'b'], lambda x: x == 'b'))
# [1, 3]
more_itertoolsüçüncü taraf bir kütüphanedir > pip install more_itertools.
conda installson zamanlarda performansta çok kararsız hale gelmiş olsa da)
Tüm oluşumlar için bir çözüm daha (yinelenirse özür dilerim):
values = [1,2,3,1,2,4,5,6,3,2,1]
map(lambda val: (val, [i for i in xrange(len(values)) if values[i] == val]), values)
Python2'de filter () kullanımı.
>>> q = ['Yeehaw', 'Yeehaw', 'Googol', 'B9', 'Googol', 'NSM', 'B9', 'NSM', 'Dont Ask', 'Googol']
>>> filter(lambda i: q[i]=="Googol", range(len(q)))
[2, 4, 9]
Bir varsayılan karar oluşturabilirsiniz
from collections import defaultdict
d1 = defaultdict(int) # defaults to 0 values for keys
unq = set(lst1) # lst1 = [1, 2, 2, 3, 4, 1, 2, 7]
for each in unq:
d1[each] = lst1.count(each)
else:
print(d1)
Numaralandırma (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]
>>>
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]
for n, i in enumerate([1, 2, 3, 4, 1]):
if i == 1:
print(n)
Çıktı:
0
4
for-loop:enumerateve liste kavrayışı daha verimli ve pitoniktir, ancak bu yanıt, bu yerleşik işlevlerin bazılarını kullanmasına izin verilmeyen öğrencileri hedefler .indicesfor i in range(len(x)):temel olarak bir dizin konumları listesi üzerinden yinelenen bir döngü oluşturun[0, 1, 2, 3, ..., len(x)-1]inerede, x[i]bir maç olduğunu value, hiçindices
def get_indices(x: list, value: int) -> list:
indices = list()
for i in range(len(x)):
if x[i] == value:
indices.append(i)
return indices
n = [1, 2, 3, -50, -60, 0, 6, 9, -60, -60]
print(get_indices(n, -60))
>>> [4, 8, 9]
get_indicesile uygulanan tip ipuçları . Bu durumda, liste, nbir grup ints'dir, bu nedenle valuede bir int.while-loopve .index:.index, listede yer almazsa bir hata oluşacağı try-exceptiçin hata işleme için kullanın .ValueErrorvaluedef get_indices(x: list, value: int) -> list:
indices = list()
i = 0
while True:
try:
# find an occurrence of value and update i to that index
i = x.index(value, i)
# add i to the list
indices.append(i)
# advance i by 1
i += 1
except ValueError as e:
break
return indices
print(get_indices(n, -60))
>>> [4, 8, 9]
get_indeicesnormal liste anlamadan biraz daha hızlıdır (~% 15). Anlamaya çalışıyorum.
Python 2 kullanıyorsanız, bununla aynı işlevselliği elde edebilirsiniz:
f = lambda my_list, value:filter(lambda x: my_list[x] == value, range(len(my_list)))
my_listDizinlerini almak istediğiniz liste nerede ve valuearanan değerdir. Kullanımı:
f(some_list, some_element)
Belirli dizinler arasındaki tüm öğelerin konumlarını aramanız gerekirse, bunları belirtebilirsiniz:
[i for i,x in enumerate([1,2,3,2]) if x==2 & 2<= i <=3] # -> [3]