1

I have the following list:

mylist = [
   { 'frame': { 'aaa': 50 } },
   { 'frame': { 'bbb': 12 } },
   { 'frame': { 'ccc': 23 } },
   { 'frame': { 'ddd': 72 } }
]

I was hoping to sort the list based on those integer values with different keys 'aaa', bbb', 'ccc', etc.

I have seen this question but the keys are consistent to this problem.

Any help is highly appreciated!

EDIT: My desired output is:

sorted_list = [
       { 'frame': { 'ddd': 72 } },
       { 'frame': { 'aaa': 50 } },
       { 'frame': { 'ccc': 23 } },
       { 'frame': { 'bbb': 12 } }
]
  • Do the dictionaries always have only one key/value pair? If so, sort by the fist item in `values()`. – Mark Mar 26 '21 at 00:03
  • I don't understand. What is the expected result for this input? Which key/value pair will you care about from the nested dictionary, and how do you know? – Karl Knechtel Mar 26 '21 at 00:05
  • @MarkM yes. In my case, the key is 'frame' and its value is a dictionary. – J. A. De la Peña Mar 26 '21 at 00:05
  • Anyway, the approach is the same as in the linked answer. You need to be able to write a function that tells you a value that corresponds to each item of `mylist`, and then you will sort according to those values, by using `key=`. – Karl Knechtel Mar 26 '21 at 00:06
  • 1
    "In my case, the key is 'frame' and its value is a dictionary" No; we're talking about *that dictionary which is the value*. – Karl Knechtel Mar 26 '21 at 00:06
  • @KarlKnechtel please see the edited question – J. A. De la Peña Mar 26 '21 at 00:09
  • Okay, so you want to put `{ 'frame': { 'ddd': 72 } }` first because the `72` value associated with the `'ddd'` key is the largest one found, right? *How do you know the `'ddd'` key is the one you want to look at, and not any of the other keys in `{ 'ddd': 72 }`*? Like, in the example you showed, there aren't any other keys. If there were, it obviously would be a problem. That's why you were asked to clarify. – Karl Knechtel Mar 26 '21 at 00:29
  • @KarlKnechtel Sorry for missing those important details, the keys are unique. Meaning, there is only one 'ddd' key in the entire list. – J. A. De la Peña Mar 26 '21 at 00:31

3 Answers3

1
mylist = sorted(mylist, key=lambda k: -list(k["frame"].values())[0])
print(mylist)

Prints:

[{'frame': {'ddd': 72}}, 
 {'frame': {'aaa': 50}}, 
 {'frame': {'ccc': 23}}, 
 {'frame': {'bbb': 12}}]
Andrej Kesely
  • 168,389
  • 15
  • 48
  • 91
  • 2
    Instead of negating the value returned by the `lambda`, you can also use `reverse=True` in the `sorted` call. Like: `sorted(mylist, key=lambda k: list(k["frame"].values())[0], reverse=True)`. This has the advantage that it also works for `key` functions that compute a non-numeric (but still sortable) result (such as a string). – Karl Knechtel Mar 26 '21 at 00:30
1

You can use sorted with a lambda for the key which just returns the first value stored in the dict under the 'frame' key.

We get the first value by using next with iter. This avoids creating a new list object.

We also pass the reverse parameter as True, so we get biggest numbers first. :

>>> mylist = [
...    { 'frame': { 'aaa': 50 } },
...    { 'frame': { 'bbb': 12 } },
...    { 'frame': { 'ccc': 23 } },
...    { 'frame': { 'ddd': 72 } }
... ]

>>> sorted(mylist, key=lambda d: next(iter(d['frame'].values())), reverse=True)
[{'frame': {'ddd': 72}},
 {'frame': {'aaa': 50}},
 {'frame': {'ccc': 23}},
 {'frame': {'bbb': 12}}]
Peter Wood
  • 23,859
  • 5
  • 60
  • 99
0

A slight tweak to the answer in that question gets you this which works.

sorted_list = sorted(mylist, key=lambda k: k['frame'][list(k['frame'].keys())[0]], reverse=True)

Essentially it just goes down into the list, To then sort by the values. Set reverse to True to get it to reverse the list.

jbflow
  • 578
  • 2
  • 16