Reputation: 857
I have a list of dictionaries with multiple keys and I would like to get multiple lists each with the indices of the dictionaries, sorted by a particular key.
For example, I have the following list
a = [{"name": "Zoe", "age": 13}, {"name": "Adam", "age": 31}]
I know that I can do the following
from operator import itemgetter
sorted(a, key=itemgetter("name"))
to get the following
[{'name': 'Adam', 'age': 31}, {'name': 'Zoe', 'age': 13}]
but I really want to be able to get two lists with the indices instead:
[1, 0] # order of the elements in `a` as sorted by name
[0, 1] # order of the elements in `a` as sorted by age
My real dictionary has many more key-value pairs and it's more efficient for me to return a
and the additional lists with indices as sorted by different keys rather than multiple sorted lists of a
.
Upvotes: 1
Views: 181
Reputation: 55469
A simple way to do this is to add an index field to the dicts in your list.
from operator import itemgetter
a = [{'name':"Zoe", 'age':13}, {'name':"Adam", 'age':31}]
for i, d in enumerate(a):
d['index'] = i
def get_indices(seq):
return[d['index'] for d in seq]
by_name = sorted(a, key=itemgetter("name"))
print by_name
print get_indices(by_name)
by_age = sorted(a, key=itemgetter("age"))
print by_age
print get_indices(by_age)
output
[{'index': 1, 'age': 31, 'name': 'Adam'}, {'index': 0, 'age': 13, 'name': 'Zoe'}]
[1, 0]
[{'index': 0, 'age': 13, 'name': 'Zoe'}, {'index': 1, 'age': 31, 'name': 'Adam'}]
[0, 1]
Of course, you don't need to keep the sorted lists of dicts, you could just do
by_name = get_indices(sorted(a, key=itemgetter("name")))
Upvotes: 2
Reputation: 1121714
You can produce a sorted list of indices by producing a range()
, and then adjusting the sort key to translate an index to a specific value from a dictionary from the a
list:
sorted(range(len(a)), key=lambda i: a[i]['name'])
sorted(range(len(a)), key=lambda i: a[i]['age'])
If you know the keys up front, just loop and produce multiple lists; you could perhaps create a dictionary keyed by each sorting key:
{key: sorted(range(len(a)), key=lambda i: a[i][key]) for key in ('name', 'age')}
The above dictionary comprehension then gives you access to each sorted list based on the sort key alone:
>>> a = [{'name': "Zoe", 'age': 13}, {'name': "Adam", 'age': 31}]
>>> {key: sorted(range(len(a)), key=lambda i: a[i][key]) for key in ('name', 'age')}
{'age': [0, 1], 'name': [1, 0]}
Upvotes: 5