2013-10-31 62 views
3

假設我有一個列表[10,5,7],我想將它縮小爲表示相對順序[3,1,2]。我不知道如何在Python中進行轉換。Python按順序減少列表

+1

這不是一個真正的減少; 「減少」通常意味着你以比你剛開始時更少的值結束(實際上,從許多列表中通常是1)。 –

+0

檢查這一個: http://stackoverflow.com/questions/10777271/python-using-enumerate-inside-list-comprehension 查找到字典和枚舉。 – crownedzero

+0

@PatrickKostjens真令人厭惡的蠻力方法,我從1迭代到列表中的最大值,然後在我遇到它們時檢查訂單,但它超級慢,可能不值得使用 – user2175923

回答

1
start = [10, 5, 7] 

排序它

step1 = sorted(start) #if you have duplicates, sorted(set(start)) to uniquify 

做一個查找表

lookup = {v:i for i,v in enumerate(step1,1)} 

讓您的新名單。

[lookup[x] for x in start] 
Out[9]: [3, 1, 2] 

這是O(nlogn),而不是爲O(n ** 2)使用重複的index搜索解決方案。時序:

test = [randrange(0,10000) for _ in range(10000)] 

def f(): 
    std = sorted(test) 
    return [std.index(e)+1 for e in test] 

def g(): 
    step1 = sorted(test) 
    lookup = {v:i for i,v in enumerate(step1,1)} 
    return [lookup[x] for x in test] 

%timeit f() 
1 loops, best of 3: 1.17 s per loop 

%timeit g() 
100 loops, best of 3: 6.58 ms per loop 
+0

這個答案假定輸入列表包含唯一值。 –

+0

@SimeonVisser是的。添加了一條評論來解決這個問題 – roippi

6

試試這個,假設有列表中沒有重複的元素:

lst = [10, 5, 7] 
std = sorted(lst) 

[std.index(e)+1 for e in lst] 
=> [3, 1, 2] 
+1

這是O(n ** 2)所以根據OP的需求可能太「蠻力」。 – roippi

0
a = [10,5,7] 
b = sorted(a) 
newList = [] 
for i in a: 
    newList.append(b.index(i)) 

print newList 

注意輸出爲[2,0,1],因爲該列表是從零開始的,你可以修改如果需要,可以附加b.index(i)+1。

0
In [29]: L=[10,5,7] 

In [30]: %paste 
inds = {} 
for v,k in enumerate(sorted(L),1): 
    if k not in inds: 
    inds[k] = [] 
    inds[k].append(v) 
answer = [inds[k].pop() for k in L] 

## -- End pasted text -- 

In [31]: answer 
Out[31]: [3, 1, 2]