Reputation: 1333
These are the logical steps that I need to perform on my list of lists
a = [[5,2],[7,4],[0,3]]
sort the list of lists in such a way that the output looks something like
7,5,4,3,2,0
take the coordinates of the sorted elements in the original list, which in this case should produce as output
(1,0)
(0,0)
(1,1)
(2,1)
(0,1)
(2,0)
I tried using of sort, sorted
and argwhere
in different ways but I am not getting sensible results, I guess first of all because sort
and sorted
can sort a list following only one axis at a time
Upvotes: 8
Views: 1668
Reputation: 107347
Use Numpy
, which is pretty much faster than regular python code when you are dealing with larger arrays:
In [21]: a = np.array([[5,2],[7,4],[0,3]])
In [22]: x, y = np.unravel_index((-a).argsort(axis=None), a.shape)
In [23]: indices = np.column_stack((x, y))
In [24]: indices
Out[24]:
array([[1, 0],
[0, 0],
[1, 1],
[2, 1],
[0, 1],
[2, 0]])
In [25]: a[x, y]
Out[25]: array([7, 5, 4, 3, 2, 0])
Upvotes: 2
Reputation: 3221
You can use a series of list comprehensions and zip
blocks, although the readability suffers:
n, idxs = zip(*sorted(zip([i for sl in a for i in sl], [(col, row) for col in range(len(a)) for row in range(len(a[col]))]), key=lambda x: x[0], reverse=True))
print n, idxs
>>> (7, 5, 4, 3, 2, 0) ((1, 0), (0, 0), (1, 1), (2, 1), (0, 1), (2, 0))
If you need a dict, just replace the zip(*..)
layer with dict()
Upvotes: 2
Reputation: 55499
This code will work for a list of lists. The internal lists don't have to be the same length.
At each level we iterate over a list using enumerate
to get the list item and its index. At the top level, each item is another list, and the inner loop iterates over each of those lists to get their indices and values, storing the indices (as a tuple) in a tuple that also contains the value. We then sort the resulting list of tuples (b
) on the values, and then split it using zip
into a tuple of all the indices and a tuple of the values.
from operator import itemgetter
a = [[5, 2], [7, 4], [0, 3]]
b = [((i, j), v) for i, t in enumerate(a) for j, v in enumerate(t)]
b.sort(key=itemgetter(-1), reverse=True)
print(b)
coords, vals = zip(*b)
print(vals)
print(coords)
output
[((1, 0), 7), ((0, 0), 5), ((1, 1), 4), ((2, 1), 3), ((0, 1), 2), ((2, 0), 0)]
(7, 5, 4, 3, 2, 0)
((1, 0), (0, 0), (1, 1), (2, 1), (0, 1), (2, 0))
Upvotes: 8
Reputation: 67988
You can flatten the list and then use it to sort and find indices.
a = [[5,2],[7,4],[0,3]]
c = reduce(lambda x, y: x+y, a)
b = sorted(c, reverse=True)
for i in b:
print c.index(i)/2, c.index(i)%2
Output:
1 0
0 0
1 1
2 1
0 1
2 0
Upvotes: 1
Reputation: 239643
Create a dictionary with the keys as the actual coordinates and the values as the numbers themselves, like this
>>> a = [[5, 2], [7, 4], [0, 3]]
>>> positions = {
... (idx1, idx2): col
... for idx1, row in enumerate(a)
... for idx2, col in enumerate(row)
... }
>>> positions
{(0, 1): 2, (2, 0): 0, (0, 0): 5, (1, 0): 7, (1, 1): 4, (2, 1): 3}
Now, sort the keys (coordinates) of positions
based on their values, like this
>>> sorted(positions, key=positions.get, reverse=True)
[(1, 0), (0, 0), (1, 1), (2, 1), (0, 1), (2, 0)]
Upvotes: 8