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
Use enumerate() to get the indices of a sorted array Call sorted(iterable, key: NoneType=None) with the enumerate object as iterable and operator. itemgetter(1) as key to construct a sorted list of index-element tuples.
The primary difference between the two is that list. sort() will sort the list in-place, mutating its indexes and returning None , whereas sorted() will return a new sorted list leaving the original list unchanged.
To sort a list of lists using the element at index n of the inner list, We will pass the inner lists as the input argument to the lambda function. We will use the element at index n of the inner list as the expression in the lambda function.
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))
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)]
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With