如何单元化元组元素?

时间:2010-09-08 07:16:39

标签: python algorithm

我有一个词典结果元组。

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

我想要统一它。在unqify操作result = ({'name': 'xxx', 'score': 120L }, {'name': 'yyy', 'score': 10L})

之后

result仅包含one dictionary namedict应包含maximum score。最终结果应采用相同的格式,即字典元组。

4 个答案:

答案 0 :(得分:2)

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')))

我确信有一个较短的解决方案,但您无法先避免以某种方式按名称过滤分数,然后找到每个名称的最大值。

将分数存储在名称为键的字典中绝对是可取的。

答案 1 :(得分:2)

我会创建一个中间字典,将每个名称映射到该名称的最大分数,然后将其转回一个dicts元组:

>>> 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})

注意: 1)我已将{'name': 'yyy', 'score': 20}添加到您的示例数据中,以显示它使用具有多个名称的元组。

2)我使用defaultdict,假设得分的最小值为零。如果得分可能为负,则需要将defaultdict(int)的int参数更改为返回小于最小可能得分的数字的函数。

顺便提一下,我怀疑拥有一个字典元组并不是你想要做的最好的数据结构。您是否考虑过替代方案,例如单个词典,或者每个名称的分数列表?

答案 2 :(得分:1)

我会重新考虑数据结构以更好地满足您的需求(例如dict用名称和分数列表作为值进行哈希),但我会这样做:

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

答案 3 :(得分:0)

怎么样......

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())