0

I am trying to sort a dictionary containing lists. For example, if I have this dictionary:

a = {'q': {3: [4, 2, 7]}, 'a': {1: [5, 45, 11]}, 'e': {23: [11, 45, 2]}}

I want the output after sorting to be:

[(e, {23:[11,45,2}]), (a, {1:[5,45,11]}), (q,{3,[4,2,7]})] 

I am actually sorting in reverse, using the first item in the list as the key for the sort.

In the event that the first items of two lists are identical, like above, I sort for the string associated with the list (main key) in alphabetical order.

I am not sure if I can get the output of tuples with dictionary in it as I am sorting for that the list in that dictionary.

I have tried this code:

sorted((x,b.items(), key=lambda x:[1][2]) for x,b in a.items())

It raised an error for invalid syntax, and I can't figure out what's wrong.

2
  • What did the syntax error say? Commented Feb 6, 2013 at 0:46
  • @user1988876 In the original post, you say that you want to use the item at list.index[1] as the sort key. By this, do you mean the first (which would be list[0]), or second item in each list? Commented Feb 6, 2013 at 13:41

3 Answers 3

2

Let's break the problem in parts. You really want to sort the list a.items(). So:

>>> to_sort = a.items()
>>> to_sort
[('q', {3: [4, 2, 7]}), ('a', {1: [5, 3, 11]}), ('e', {23: [11, 45, 2]})]

Now, for each element in the list, you have a tuple of a value ('q' etc.) and a dictionary. Presumably, each dictionary contains only one key, and you want to use the index-1 element of each dictionary's value as the primary key. So, the key for the first element should be: to_sort[0][1].values()[0][1]: to_sort[0][1] gives you the dictionary {3: [4, 2, 7]}, .values() gives you the list [[4, 2, 7]], and [0][1] on that gives you 2. The secondary sort key is simply to_sort[0].

So we get:

>>> sorted(to_sort, key=lambda x: (x[1].values()[0][1], x[0]))
[('q', {3: [4, 2, 7]}), ('a', {1: [5, 3, 11]}), ('e', {23: [11, 45, 2]})]

We are almost there. Now you just need to tell sort that you want reversed output:

>>> sorted(to_sort, key=lambda x: (x[1].values()[0][1], x[0]), reverse=True)
[('e', {23: [11, 45, 2]}), ('a', {1: [5, 3, 11]}), ('q', {3: [4, 2, 7]})]

Is this what you want?

If you want a one-liner, you can do:

>>> sorted(a.items(), key=lambda x: (x[1].values()[0][1], x[0]), reverse=True)
Sign up to request clarification or add additional context in comments.

1 Comment

Fantastic step-by-step explanation.
1

At least in the interactive interpreter, the full error message should show you exactly where the error is happening:

>>> sorted((x,b.items(), key=lambda x:[1][2]) for x,b in a.items())
  File "<stdin>", line 1
    sorted((x,b.items(), key=lambda x:[1][2]) for x,b in a.items())
                            ^
SyntaxError: invalid syntax

Notice that the ^ is right below the =.

That doesn't tell you why you got an error there, but at least it tells you where to look.

And once you look carefully, notice this sub-expression:

(x,b.items(), key=lambda x:[1][2])

So that's a tuple, whose third member is key=lambda x:[1][2]. But that isn't valid as an expression. So, you've got some parentheses in the wrong place. Or, rather, you've added the key parameter to the wrong place. I think you meant this:

sorted(((x,b.items()) for x,b in a.items()), key=lambda x:[1][2])

No SyntaxError there. It looks like that's going to get an IndexError later on, but you can deal with that when you get there.

Comments

0

I'm not 100% sure, but are you ultimately after?

>>> a = {'q': {3: [4, 2, 7]}, 'a': {1: [5, 3, 11]}, 'e': {23: [11, 45, 2]}}
>>> new_order = sorted(a, key=lambda L: a[L].values(), reverse=True)
>>> zip(new_order, map(a.get, new_order))
[('e', {23: [11, 45, 2]}), ('a', {1: [5, 3, 11]}), ('q', {3: [4, 2, 7]})]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.