2016-08-03 61 views
8

我試圖扭轉由enumerate給出的索引,同時保留列表的原始順序列舉。python枚舉僅反向索引

假設我有以下幾點:

>> range(5) 
[0, 1, 2, 3, 4] 

如果我列舉這個我會得到如下:

>> list(enumerate(range(5))) 
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)] 

但是我想逆轉枚舉提供的索引,使我得到:

[(4, 0), (3, 1), (2, 2), (1, 3), (0, 4)] 

到目前爲止,我有以下代碼:

reversed(list(enumerate(reversed(range(5))))) 

我只是想知道是否有更好的方法來做到這一點?

回答

9

如何使用zip代替反向範圍?

>>> zip(range(9, -1, -1), range(10)) 
[(9, 0), (8, 1), (7, 2), (6, 3), (5, 4), (4, 5), (3, 6), (2, 7), (1, 8), (0, 9)] 


>>> def reversedEnumerate(l): 
     return zip(range(len(l)-1, -1, -1), l) 
>>> reversedEnumerate(range(10)) 
[(9, 0), (8, 1), (7, 2), (6, 3), (5, 4), (4, 5), (3, 6), (2, 7), (1, 8), (0, 9)] 

由於@julienSpronk表明,使用izip得到一個發電機,也xrange

import itertools 
>>> import itertools 
>>> def reversedEnumerate(l): 
...  return itertools.izip(xrange(len(l)-1, -1, -1), l) 
...  
>>> reversedEnumerate(range(10)) 
<itertools.izip object at 0x03749760> 
>>> for i in reversedEnumerate(range(10)): 
...  print i 
...  
(9, 0) 
(8, 1) 
(7, 2) 
(6, 3) 
(5, 4) 
(4, 5) 
(3, 6) 
(2, 7) 
(1, 8) 
(0, 9) 
+0

也是一個不錯的主意。 – RemcoGerlich

+0

或'itertools.izip'來得到一個生成器 –

+0

謝謝!我總是忘記拉鍊! – rozzy

2

只要看看你的列表的長度和減去該指數...

L = range(5) 

for i, n in L: 
    my_i = len(L) -1 - i 
    ... 

或者,如果你真的需要一臺發電機:

def reverse_enumerate(L): 
    # Only works on things that have a len() 
    l = len(L) 
    for i, n in enumerate(L): 
     yield l-i-1, n 

enumerate()不可能做到這一點,因爲它與泛型迭代器一起工作。例如,你可以傳遞它無限的迭代器,甚至沒有「反向索引」。

4

我不知道,如果這個解決方案是對你更好,但至少它的短:

>>> [(4 - x, x) for x in range(5)] 
[(4, 0), (3, 1), (2, 2), (1, 3), (0, 4)] 
2

假設您的列表不長,您不會遇到性能錯誤,您可以使用list(enumerate(range(5)[::-1]))[::-1]

測試:

>>> list(enumerate(range(5)[::-1]))[::-1] [(0, 4), (1, 3), (2, 2), (3, 1), (4, 0)]

+0

請仔細閱讀他所要求的內容 – Netwave

+0

我提供了最理想的方式來做到這一點,據我所知。但是,這個問題很有趣。 – user3036878

+0

他想要索引被顛倒,而不是列表 – Netwave

2

其實我使用的是相同的邏輯@RemcoGerlich做了,但是我用list comprehension直接,這使得現在的代碼變成1班輪:

def generatelist(x): 
    return [(x-1-i,n) for i,n in enumerate(range(x))] 

關於選擇generatorlist comprehension的難題,here是建議的方式:

基本上,如果您所做的只是迭代一次,則使用生成器表達式。如果你想存儲和使用生成的結果,那麼你可能會更好地使用列表理解。

0

如果你想重新使用它好幾次,你可以讓你自己的發電機:

def reverse_enum(lst): 
    for j, item in enumerate(lst): 
     yield len(lst)-1-j, item 

print list(reverse_enum(range(5))) 
# [(4, 0), (3, 1), (2, 2), (1, 3), (0, 4)] 

def reverse_enum(lst): 
    return ((len(lst)-1-j, item) for j, item in enumerate(lst)) 
0

只需使用len(lst)-i我到處被使用。或:

[(len(range(5)) - x, x) for x in range(5)]