0

Lets say you have this nested dictionary:

myDict = { 
          0: { 'bob': [1, 9, 4, 6, 7],
               'jack': [2, 6, 9, 8, 5, 0]}
          1: { 'dom': [1, 7, 8, 5],
               'dean': [1, 9]}
          }

How do you sort myDict[0] by the greatest of the last three values, so the output can be something like (with jack ahead of bob):

jack -> 8

bob -> 7

Thank you in advance

Scott
  • 6,089
  • 4
  • 34
  • 51
Aweys
  • 23
  • 5
  • 1
    You do not *sort* dictionaries, period. – deceze Jun 08 '15 at 15:35
  • @deceze I think he means the list values in the dictionary. – Malik Brahimi Jun 08 '15 at 15:36
  • @MalikBrahimi But the values are also dictionaries. – SuperBiasedMan Jun 08 '15 at 15:37
  • possible duplicate of [Sort a Python dictionary by value](http://stackoverflow.com/questions/613183/sort-a-python-dictionary-by-value) – SuperBiasedMan Jun 08 '15 at 15:37
  • 1
    One step along your way - to get the last three values of a list, use `lst[-3:]`. The `max` function will return the greatest of those three values. "Sorting", as stated, is not possible in a standard Python dictionary, although you could use an [OrderedDict](https://docs.python.org/2/library/collections.html#collections.OrderedDict). – jayelm Jun 08 '15 at 15:39
  • The question is very unclear as it stands, it would help if you would try to re-phrase your question, keeping in mind that dictionaries are not ordered. What exactly is your goal? – Jonas Schäfer Jun 08 '15 at 15:42
  • guys, the goal is to sort the lists inside the dictionary... the requirement for the sort is the last 3 elements of the list. `max(myDict[0]['bob'][-3:])` would return the max value of the last 3 for bob... – John Ruddell Jun 08 '15 at 15:44

3 Answers3

1

one solution is to use an orderd dictionary:

from collections import OrderedDict

def my_ordered_dict(d):
    return OrderedDict(sorted(d.items(),
                              key=lambda t: max(t[1][-3:]),
                              reverse=True))
myDict = { 
        0: my_ordered_dict({'bob': [1, 9, 4, 6, 7],
                            'jack': [2, 6, 9, 8, 5, 0]}),
        1: my_ordered_dict({'dom': [1, 7, 8, 5],
                            'dean': [1, 9]})
          }

print myDict[0]
print myDict[1]

ouputs:

OrderedDict([('jack', [2, 6, 9, 8, 5, 0]), ('bob', [1, 9, 4, 6, 7])])
OrderedDict([('dean', [1, 9]), ('dom', [1, 7, 8, 5])])

Please note in the second case dean gets ahead of dom even if its list has two elements only.

Pynchia
  • 10,996
  • 5
  • 34
  • 43
-1

Code :

myDict = { 
          0: { 'bob': [1, 9, 4, 6, 7],
               'jack': [2, 6, 9, 8, 5, 0]},
          1: { 'dom': [1, 7, 8, 5],
               'dean': [1, 9]}
          }
myDict[0] = sorted(myDict[0].items(),key=lambda (k,v) : max(v[-3:]),reverse=True)
print(myDict)

Output :

{0: [('jack', [2, 6, 9, 8, 5, 0]), ('bob', [1, 9, 4, 6, 7])], 1: {'dean': [1, 9], 'dom': [1, 7, 8, 5]}}

Explanation :
Convert myDict[0] to (key,value) pairs & then sort it by the max value of the last 3 elements in the value list.

darthShadow
  • 1,027
  • 1
  • 12
  • 24
  • Thanks, I understand why that works, but I keep on getting a syntax error with the '(' part of '(k, v)'? – Aweys Jun 10 '15 at 13:13
  • @Aweys Tried it just now. No errors on my side. Check it here : [Ideone](https://ideone.com/nmAbJ6) – darthShadow Jun 10 '15 at 13:16
  • I did this, but it doesn't work: `for key in sorted(myDict[0].items(), key=lambda (k,v) : max(v[-3:0]), reverse = True): print ('%s: %s' % (key, myDict[0][key]))` – Aweys Jun 10 '15 at 13:39
  • @Aweys It should be : for **(key,value)** in sorted(myDict[0].items(), key=lambda (k,v) : max(v[-3:]), reverse = True): print ('%s: %s' % (key, myDict[0][key])) as it returns a set of key,value tuples – darthShadow Jun 10 '15 at 13:43
  • It still returns ` syntax error: invalid syntax` with the `(` part of `(k, v)`...btw, I'm running python 3 – Aweys Jun 10 '15 at 13:46
  • @Aweys You cannot pass multiple arguments to lambda in Python 3 [lambda](http://www.diveintopython3.net/porting-code-to-python-3-with-2to3.html#tuple_params) . So the code now becomes : `for (key,value) in sorted(myDict[0].items(), key=lambda t : max(t[1][-3:]), reverse = True): print ('%s: %s' % (key, myDict[0][key]))` – darthShadow Jun 10 '15 at 14:04
  • Now it says `ValueError: max() arg is an empty sequence`? – Aweys Jun 11 '15 at 09:10
  • @Aweys Could u post ur whole program? – darthShadow Jun 11 '15 at 10:49
-2

Dictionaries are accessed by key's, you can't sort them in python. You can however, EXTRACT the data and put it into a list - after which, sorting the data is rather easy!

myDict = { 
          0: { 'bob': [1, 9, 4, 6, 7],
               'jack': [2, 6, 9, 8, 5, 0]}
          1: { 'dom': [1, 7, 8, 5],
               'dean': [1, 9]}
          }

For example, you can do:

list_one = (myDict[0]['bob'][-3:])

If you want the greatest of the last three values:

greatest = list.sort(list_one)[-1] #gets the last value
Mmm Donuts
  • 9,551
  • 6
  • 27
  • 49
  • The requirement is impossible unless you re-serialize the data :O. Getting the list values and retrieving the max would be the first couple of steps. – Mmm Donuts Jun 08 '15 at 15:44