Python'da, bir listeyi başka bir listeyle nasıl indekslerim?


130

Bunun gibi başka bir listeyi içeren bir listeyi indekslemek istiyorum

L = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
Idx = [0, 3, 7]
T = L[ Idx ]

ve T, ['a', 'd', 'h'] içeren bir liste olmalıdır.

Daha iyi bir yolu var mı

T = []
for i in Idx:
    T.append(L[i])

print T
# Gives result ['a', 'd', 'h']

Yanıtlar:


241
T = [L[i] for i in Idx]

7
Bu bir döngüden daha mı hızlı yoksa daha mı kısa?
Daniel Andrén

10
@daniel: her ikisi de + önerilir
SilentGhost

14
Hızlı bir zamanlama testi (pysco veya başka bir şey yok, öyleyse ne yaparsan yap) liste anlayışını döngüden 2,5 kat daha hızlı gösterdi (1000 öğe, 10000 kez tekrarlandı).
James Hopkin

2
(harita ve lambda kullanmak daha da yavaştır - her yinelemede bir işlev çağırdığı için beklenebilir)
James Hopkin

+1 İndeksleme listesi gelişigüzel ise, o zaman bir liste karşılıkları yoldur. Mümkün olduğunda, burada durum böyle görünmüyor, dilimlerin daha da hızlı olduğunu düşünüyorum.
Jaime

41

Numpy kullanıyorsanız, aşağıdaki gibi genişletilmiş dilimleme yapabilirsiniz:

>>> import numpy
>>> a=numpy.array(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])
>>> Idx = [0, 3, 7]
>>> a[Idx]
array(['a', 'd', 'h'], 
      dtype='|S1')

... ve muhtemelen çok daha hızlıdır (eğer performans, uyuşmuş içe aktarma ile uğraşmak için yeterli bir endişe kaynağıysa)


5
Hızlı timeit testim np.array kullanmanın aslında neredeyse 3 kat daha yavaş olduğunu gösterdi (diziye dönüştürme dahil).
Andrzej Pronobis

Yine de dizi işlemleri için dönüştürmeniz gerekirse daha iyi çalışır. Normal liste işlemleri için çok zaman alıcı.
frankliuao

9

İşlevsel bir yaklaşım:

a = [1,"A", 34, -123, "Hello", 12]
b = [0, 2, 5]

from operator import itemgetter

print(list(itemgetter(*b)(a)))
[1, 34, 12]

bYalnızca bir öğe içeriyorsa bu işe yaramaz .
blhsing


5

Bu yaklaşımların hiçbirinden memnun değildim, bu yüzden Flexlisttamsayı, dilim veya indeks listesi ile esnek indekslemeye izin veren bir sınıf buldum :

class Flexlist(list):
    def __getitem__(self, keys):
        if isinstance(keys, (int, slice)): return list.__getitem__(self, keys)
        return [self[k] for k in keys]

Örneğiniz için şu şekilde kullanırsınız:

L = Flexlist(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])
Idx = [0, 3, 7]
T = L[ Idx ]

print(T)  # ['a', 'd', 'h']

Bu da Python'un gücünü ve esnekliğini gösterir!
crowie

Bunu mevcut kod için genişletmek çok kolaydır. Sadece arayın existing_list = Flexlist(existing_list)ve herhangi bir kodu bozmadan gerekli işlevselliğe sahibiz
Yesh

1
L= {'a':'a','d':'d', 'h':'h'}
index= ['a','d','h'] 
for keys in index:
    print(L[keys])

Ben bir Dict addarzu keyskullanırdımindex


0

Aşağıdaki gibi __getitem__birleştirilmiş yöntemi de kullanabilirsiniz map:

L = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
Idx = [0, 3, 7]
res = list(map(L.__getitem__, Idx))
print(res)
# ['a', 'd', 'h']
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.