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"]
enumerate
2.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, numpy
bu 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 where
getiriler bir demet(array([2, 8], dtype=int64),)
all_id_resp_address
olmalıdır np.array
değil list
.
list
ve str
açıkçası geçtin False
için np.where
. np.array
İkram etmekle kıyaslandığında . bir dizi boolean değer elde edersiniz. Sonra o dizinin np.where
tüm True
değ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)
enumerate
Bü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.timeit
rastgele 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 install
son 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
:enumerate
ve liste kavrayışı daha verimli ve pitoniktir, ancak bu yanıt, bu yerleşik işlevlerin bazılarını kullanmasına izin verilmeyen öğrencileri hedefler .indices
for 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]
i
nerede, 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_indices
ile uygulanan tip ipuçları . Bu durumda, liste, n
bir grup int
s'dir, bu nedenle value
de bir int
.while-loop
ve .index
:.index
, listede yer almazsa bir hata oluşacağı try-except
için hata işleme için kullanın .ValueError
value
def 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_indeices
normal 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_list
Dizinlerini almak istediğiniz liste nerede ve value
aranan 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]