2014-08-28 15 views
5

我有一個n數字的數組,例如[1,4,6,2,3]。排序後的數組是[1,2,3,4,6],舊數組中的這些數字的索引是0,3,4,1和2.給定一個n數組的數組,可以找到這個索引數組的最佳方法是什麼?對列表進行排序,然後按照原始順序給出元素索引

我的想法是運行每個元素的訂單統計。然而,由於我不得不多次重寫這個函數(比賽中),我想知道是否有一個簡短的方法來做到這一點。

+1

你能證明你已嘗試過? – whereswalden 2014-08-28 02:07:59

回答

11
>>> a = [1,4,6,2,3] 
>>> [b[0] for b in sorted(enumerate(a),key=lambda i:i[1])] 
[0, 3, 4, 1, 2] 

說明:

enumerate(a)返回了由原始列表索引和值的元組的枚舉:[(0, 1), (1, 4), (2, 6), (3, 2), (4, 3)]

然後sorted基於原始數值lambda i:i[1]key排序(項目每個元組1個)。

最後,列表理解[b[0] for b in ... ]返回原始索引(每個元組的項目0)。

+0

這將創建一個枚舉列表,根據原始鍵對其進行排序,然後返回關聯的索引。一個非常有效的解決方案,關於速度和代碼長度。 – 2014-08-28 02:17:00

+0

爲什麼感謝你。我可能應該評論它,謝謝你,列表的理解可能有點難以消化。 – user2085282 2014-08-28 02:19:40

+0

完美!謝謝! – neutralino 2014-08-28 03:11:18

1

這裏是另一種方式:

>>> sorted(xrange(len(a)), key=lambda ix: a[ix]) 
[0, 3, 4, 1, 2] 

這種方法排序不是原來的名單,但其指數(帶xrange創建),使用原來的列表作爲排序鍵。

+0

如果要生成完整的索引列表來排序它,爲什麼使用'xrange'而不是'range'? – 2014-08-28 02:47:35

+0

@MarkReed:我認爲'sorted'會一次消耗'xrange'的一個元素。這意味着只會生成一個列表(排序後的版本);未排序的索引列表將不會預先生成並存儲。 – BrenBarn 2014-08-28 02:49:37

1

如果您正在對數據進行大量統計,則使用numpy數組而不是列表可能會有所幫助。如果你選擇這樣做,這會工作:

import numpy as np 
a = np.array([1,4,6,2,3]) 
b = np.argsort(a) 

argsort()可以在列表上操作爲好,但我認爲,在這種情況下,簡單地將數據拷貝到一個數組第一。

0

這應該做的伎倆:

from operator import itemgetter 
indices = zip(*sorted(enumerate(my_list), key=itemgetter(1)))[0] 
相關問題