Sort Dictionary of Dictionaries on multiple child dictionary values

前端 未结 4 594
广开言路
广开言路 2021-01-07 07:33

I have a dictionary that looks like this:

myDict = {
    \'SER12346\': {\'serial_num\': \'SER12346\', \'site_location\': \'North America\'},
    \'ABC12345\'         


        
相关标签:
4条回答
  • 2021-01-07 08:15

    Is this what you wanted?

    dicts = [{k: v} for (k,v) in myDict.items()]
    dicts.sort(key=lambda d: (d.values()[0]['site_location'], d.values()[0]['serial_num'],))
    

    Output for doing:

    import pprint
    pprint.pprint(dicts)
    

    is:

    [{'ABC12346': {'serial_num': 'ABC12346', 'site_location': 'Europe'}},
     {'SER12345': {'serial_num': 'SER12345', 'site_location': 'North America'}},
     {'SER12346': {'serial_num': 'SER12346', 'site_location': 'North America'}},
     {'ABC12345': {'serial_num': 'ABC12345', 'site_location': 'South America'}},
     {'SER12347': {'serial_num': 'SER12347', 'site_location': 'South America'}}]
    

    EDIT: I was going on your answer for the output format, but this would probably make more sense:

    dicts = myDict.items()
    dicts.sort(key=lambda (k,d): (d['site_location'], d['serial_num'],))
    

    Output:

    [('ABC12346', {'serial_num': 'ABC12346', 'site_location': 'Europe'}),
     ('SER12345', {'serial_num': 'SER12345', 'site_location': 'North America'}),
     ('SER12346', {'serial_num': 'SER12346', 'site_location': 'North America'}),
     ('ABC12345', {'serial_num': 'ABC12345', 'site_location': 'South America'}),
     ('SER12347', {'serial_num': 'SER12347', 'site_location': 'South America'})]
    
    0 讨论(0)
  • 2021-01-07 08:16

    I have a solution with cmp (I think you must use that since we use a mix of 2 keys) but it's not really pretty, I guess it can be improved:

    >>> pprint(sorted(myDict.items(), cmp=lambda x, y: cmp((x[1]['site_location'], x[1]['serial_num']), (y[1]['site_location'], y[1]['serial_num']))))
    [('ABC12346', {'serial_num': 'ABC12346', 'site_location': 'Europe'}),
     ('SER12345', {'serial_num': 'SER12345', 'site_location': 'North America'}),
     ('SER12346', {'serial_num': 'SER12346', 'site_location': 'North America'}),
     ('ABC12345', {'serial_num': 'ABC12345', 'site_location': 'South America'}),
     ('SER12347', {'serial_num': 'SER12347', 'site_location': 'South America'})]
    
    0 讨论(0)
  • 2021-01-07 08:18
    >>> import pprint
    >>> dic=myDict.items()
    >>> dic.sort(key=lambda x:(x[1]['site_location'],x[1]['serial_num']))
    >>> pprint.pprint([{k:v} for k,v in dic])
    [{'ABC12346': {'serial_num': 'ABC12346', 'site_location': 'Europe'}},
     {'SER12345': {'serial_num': 'SER12345', 'site_location': 'North America'}},
     {'SER12346': {'serial_num': 'SER12346', 'site_location': 'North America'}},
     {'ABC12345': {'serial_num': 'ABC12345', 'site_location': 'South America'}},
     {'SER12347': {'serial_num': 'SER12347', 'site_location': 'South America'}}]
    
    0 讨论(0)
  • 2021-01-07 08:25

    Dictionaries do not preserve order of items - hence can not be sorted. If you want an appearance of sorted dictionary, you need to make a sorted list and then insert it into OrderedDict class. Code snippet below illustrates this:

    from collections import OrderedDict
    
    myDict = {
        'SER12346': {'serial_num': 'SER12346', 'site_location': 'North America'},
        'ABC12345': {'serial_num': 'ABC12345', 'site_location': 'South America'},
        'SER12345': {'serial_num': 'SER12345', 'site_location': 'North America'},
        'SER12347': {'serial_num': 'SER12347', 'site_location': 'South America'},
        'ABC12346': {'serial_num': 'ABC12346', 'site_location': 'Europe'}
    }
    
    def sortfun(d):
        return (d[1]['site_location'], d[1]['serial_num'])
    
    skv = sorted(myDict.iteritems(), key=sortfun)
    sorted_dict = OrderedDict(skv)
    
    print sorted_dict
    
    0 讨论(0)
提交回复
热议问题