Say I have a list [10, 5, 7] and I want to reduce it to something that indicates the relative orders [3, 1, 2]. I don't know how to convert this in Python.
Asked
Active
Viewed 528 times
3
-
1That's not really a reduction; "reduce" usually means you wind up with fewer values than you started with (most often 1 from a list of many, in fact). – Mark Reed Oct 31 '13 at 20:23
-
Check this one out: http://stackoverflow.com/questions/10777271/python-using-enumerate-inside-list-comprehension Look into dictionary and enumerate. – crownedzero Oct 31 '13 at 20:24
-
@PatrickKostjens Really disgusting brute force approach where I iterate from 1 to the max value in the list and then check off the orders as I encounter them, but it's super slow and probably not worth using – user2175923 Oct 31 '13 at 20:25
4 Answers
6
Try this, assuming there are no duplicate elements in the list:
lst = [10, 5, 7]
std = sorted(lst)
[std.index(e)+1 for e in lst]
=> [3, 1, 2]

Óscar López
- 232,561
- 37
- 312
- 386
1
start = [10, 5, 7]
Sort it
step1 = sorted(start) #if you have duplicates, sorted(set(start)) to uniquify
Make a lookup table
lookup = {v:i for i,v in enumerate(step1,1)}
Make your new list.
[lookup[x] for x in start]
Out[9]: [3, 1, 2]
This is O(nlogn) instead of the O(n**2) solution using repeated index
searches. Timings:
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

roippi
- 25,533
- 4
- 48
- 73
0
a = [10,5,7]
b = sorted(a)
newList = []
for i in a:
newList.append(b.index(i))
print newList
Note that the output is [2,0,1] because the list is zero based, you could modify the code to append b.index(i)+1 if you wanted.

Tom Swifty
- 2,864
- 2
- 16
- 25
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]

inspectorG4dget
- 110,290
- 27
- 149
- 241