2016-07-10 67 views
2

我正在尋找一個優雅的方式來切片列表l python,給出一個ID列表l_ids。 例如,而不是寫一個優雅的方式來切片在Python中的列表,給出另一個ID列表從

new_list = [l[i] for i in l_ids] 

寫類似(僞代碼):

new_list = l[*l_ids] 

有沒有類似的方式切片列表?

我有這樣的感覺,有人已經問過,但我找不到任何參考。

編輯:這是確定的假設,所有的列表項是同一類型的

+0

itemgetter http://stackoverflow.com/questions/38276068/unpack-a-python-tuple-from-left-to-right/38276396#38276396 –

回答

0

如果所有列表元素都是同一類型的,可以使用numpy的:

from numpy import * 
new_list = array(l)[l_ids] 
+0

如果您使用numpy那麼這是一個完全不同的問題 –

+0

numpy是一個包作爲運營商(與itemgetter)是。如果它提供了一個有用和簡潔的解決方案,我不會看到任何問題。 – yuval

6

您可以使用operator.itemgetter(*items)這樣的:

from operator import itemgetter 

getter = itemgetter(*lst_ids) 
new_list = list(getter(lst)) 

另外請注意,我改名l變量lst因爲它不太模糊,並且should be avoided

可以隱式轉換的元組使用Python 3拆包的列表,@JonClements評論:

*new_list, = getter(lst) 

最後,因爲Python 3.5,你也可以使用擴展拆包:

new_list = [*getter(lst)] 
+0

如果你要提及3的擴展拆包。5,別忘了還有其他的解包方法可以在3系列中使用(儘管它不是很漂亮)'* new_lst,= getter(lst)'(因爲'list()這意味着什麼 - 我會堅持,無論如何...) –

+0

@JonClements聰明,謝謝你! – Delgan

1

你可以使用itemgetter

from operator import itemgetter 

l = ['a', 'b', 'c', 'd', 'e'] 
l_ids = [1, 2, 3] 
list(itemgetter(*l_ids)(l)) 

['b','c','d']

2

我不認爲導入任何東西都特別優雅,或pythonic。

列表解析工作,我看不出理由不使用它們(或沒有很好的理由來導入事做同樣的事情):

>>> x = [3,5,7,0,1,4,2,6] 
>>> y = ['a','b','c','d','e','f','g','h'] 
>>> nList = [y[i] for i in x] 
>>> nList 
['d', 'f', 'h', 'a', 'b', 'e', 'c', 'g'] 

列表內涵做了以下內容:

indexes = [3,5,7,0,1,4,2,6] 
data = ['a','b','c','d','e','f','g','h'] 
nList = [] 
for index in indexes: 
    nList += [data[index]] 

理解看起來非常pythonic和優雅給我。

+0

如果作者只需要創建一個這樣的列表,我認爲列表理解是完全正確的,但是'itemgetter()'是一個優雅的方式,如果它需要重複多次。 – Delgan

+0

@Delgan Ahh,好點。我想如果你有多個數據列表的ID列表相同,它會變慢。 – Tim

1

我會去與itemgetter但你也可以地圖列表.__ getitem_ _:

l = ['a', 'b', 'c', 'd', 'e'] 
l_ids = [1, 2, 3] 

new = list(map(l.__getitem__, l_ids)) 
+0

我不確定使用double leadind和尾部下劃線的方法,它在內部保留給Python,不是嗎? – Delgan

+0

這是一個意見問題,我和許多其他人經常使用相同的邏輯,以避免使用lambda調用與地圖,過濾器,即some_set .__包含__對比lambda st:x等st .. –

相關問題