How to recognize a tuple element?

I have a finite set of dictionaries.

result = ({'name': 'xxx', 'score': 120L }, {'name': 'xxx', 'score': 100L}, {'name': 'yyy', 'score': 10L}) 

I want to unify it. After the operation uniqify result = ({'name': 'xxx', 'score': 120L }, {'name': 'yyy', 'score': 10L})

result contains only one dictionary for each name , and dict should have maximum score . The end result should be in the same format as the dictionary tuple.

+4
source share
4 answers
 from operator import itemgetter names = set(d['name'] for d in result) uniq = [] for name in names: scores = [res for res in result if res['name'] == name] uniq.append(max(scores, key=itemgetter('score'))) 

I'm sure there is a shorter solution, but you cannot avoid filtering points by name in some way first, and then finding the maximum value for each name.

Storing points in a dictionary with names as keys is certainly preferable here.

+2
source

I would create an intermediate dictionary matching each name with the maximum rating for that name, and then return it to the descendants tuple:

 >>> result = ({'name': 'xxx', 'score': 120L }, {'name': 'xxx', 'score': 100L}, {'name': 'xxx', 'score': 10L}, {'name':'yyy', 'score':20}) >>> from collections import defaultdict >>> max_scores = defaultdict(int) >>> for d in result: ... max_scores[d['name']] = max(d['score'], max_scores[d['name']]) ... >>> max_scores defaultdict(<type 'int'>, {'xxx': 120L, 'yyy': 20}) >>> tuple({name: score} for (name, score) in max_scores.iteritems()) ({'xxx': 120L}, {'yyy': 20}) 

Notes: 1) I added {'name': 'yyy', 'score': 20} to your example data to show that it works with a tuple with multiple names.

2) I am using defaultdict, which assumes that the minimum value for evaluation is zero. If the rating can be negative, you will need to change the int defaultdict (int) parameter to a function that returns a number less than the minimum possible score.

By the way, I suspect that having a dictionary tuple is not the best data structure for what you want to do. Have you considered alternatives, for example, having one dict, perhaps with a list of points for each name?

+2
source

I would revise the data structure to fit your needs (e.g. dict hashed with name with list of scores as value), but I would do the following:

 import operator as op import itertools as it result = ({'name': 'xxx', 'score': 120L }, {'name': 'xxx', 'score': 100L}, {'name': 'xxx', 'score': 10L}, {'name':'yyy', 'score':20}) # groupby highscores = tuple(max(namegroup, key=op.itemgetter('score')) for name,namegroup in it.groupby(result, key=op.itemgetter('name')) ) print highscores 
+1
source

What about...

 inp = ({'name': 'xxx', 'score': 120L }, {'name': 'xxx', 'score': 100L}, {'name': 'yyy', 'score': 10L}) temp = {} for dct in inp: if dct['score'] > temp.get(dct['name']): temp[dct['name']] = dct['score'] result = tuple({'name': name, 'score': score} for name, score in temp.iteritems()) 
0
source

All Articles