Given a list of dictionaries, how can I eliminate duplicates of one key, and sort by another

前端 未结 7 902
清歌不尽
清歌不尽 2021-01-02 02:31

I\'m working with a list of dict objects that looks like this (the order of the objects differs):

[
    {\'name\': \'Foo\', \'score         


        
相关标签:
7条回答
  • 2021-01-02 03:09

    One way to do that is:

    data = collections.defaultdict(list)
    for i in my_list:
        data[i['name']].append(i['score'])
    output = [{'name': i, 'score': max(j)} for i,j in data.items()]
    

    so output will be:

    [{'score': 2, 'name': 'Baz'},
     {'score': 3, 'name': 'Foo'},
     {'score': 3, 'name': 'Bar'}]
    
    0 讨论(0)
  • 2021-01-02 03:10

    Just for fun, here is a purely functional approach:

    >>> map(dict, dict(sorted(map(sorted, map(dict.items, s)))).items())
    [{'score': 3, 'name': 'Bar'}, {'score': 2, 'name': 'Baz'}, {'score': 3, 'name': 'Foo'}]
    
    0 讨论(0)
  • 2021-01-02 03:14

    This is the simplest way I can think of:

    names = set(d['name'] for d in my_dicts)
    new_dicts = []
    for name in names:
        d = dict(name=name)
        d['score'] = max(d['score'] for d in my_dicts if d['name']==name)
        new_dicts.append(d)
    
    #new_dicts
    [{'score': 2, 'name': 'Baz'},
     {'score': 3, 'name': 'Foo'},
     {'score': 3, 'name': 'Bar'}]
    

    Personally, I prefer not to import modules when the problem is too small.

    0 讨论(0)
  • 2021-01-02 03:19

    There's no need for defaultdicts or sets here. You can just use dirt simple dicts and lists.

    Summarize the best running score in a dictionary and convert the result back into a list:

    >>> s = [
        {'name': 'Foo', 'score': 1},
        {'name': 'Bar', 'score': 2},
        {'name': 'Foo', 'score': 3},
        {'name': 'Bar', 'score': 3},
        {'name': 'Foo', 'score': 2},
        {'name': 'Baz', 'score': 2},
        {'name': 'Baz', 'score': 1},
        {'name': 'Bar', 'score': 1}
    ]
    >>> d = {}
    >>> for entry in s:
            name, score = entry['name'], entry['score']
            d[name] = max(d.get(name, 0), score)
    
    >>> [{'name': name, 'score': score} for name, score in d.items()]
    [{'score': 2, 'name': 'Baz'}, {'score': 3, 'name': 'Foo'}, {'score': 3, 'name': 'Bar'}]
    
    0 讨论(0)
  • 2021-01-02 03:19

    I think I can come up with an one-liner here:

    result = dict((x['name'],x) for x in sorted(data,key=lambda x: x['score'])).values()
    
    0 讨论(0)
  • 2021-01-02 03:21

    In case you haven't heard of group by, this is nice use of it:

    from itertools import groupby
    
    data=[
        {'name': 'Foo', 'score': 1},
        {'name': 'Bar', 'score': 2},
        {'name': 'Foo', 'score': 3},
        {'name': 'Bar', 'score': 3},
        {'name': 'Foo', 'score': 2},
        {'name': 'Baz', 'score': 2},
        {'name': 'Baz', 'score': 1},
        {'name': 'Bar', 'score': 1}
    ]
    
    keyfunc=lambda d:d['name']
    data.sort(key=keyfunc)
    
    ans=[]
    for k, g in groupby(data, keyfunc):
        ans.append({k:max((d['score'] for d in g))})
    print ans
    
    >>>
    [{'Bar': 3}, {'Baz': 2}, {'Foo': 3}]
    
    0 讨论(0)
提交回复
热议问题