如何统一元组元素?

问题描述:

我有一个结果字典的元组。如何统一元组元素?

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

我想统一它。 uniqify手术后result = ({'name': 'xxx', 'score': 120L }, {'name': 'yyy', 'score': 10L})

result仅包含one dictionary每个namedict应该有maximum score。最终的结果应该是相同的格式,即字典的元组。

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

我敢肯定有一个较短的解决方案,但你将无法避免名称以某种方式首先过滤分数,然后找到每个名字的最大。

将分数存储在名称为键的字典中肯定会在这里更可取。

+0

我认为你找到了最高分,而不是每个独特名字的最高分。 – Gabe 2010-09-08 07:25:01

+0

@加贝,不,我找到每个独特名称的最高分数。我稍微修改了这个问题。一探究竟。 – user12345 2010-09-08 07:27:39

+0

@加贝:你是对的......我被一个名字的存在误导了。 – 2010-09-08 07:41:04

我会创建一个中间字典中的每个名称映射到最高得分为名称,然后将其回类型的字典元组算账:

>>> 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,假设score的最小值为零。如果分数可能为负数,则需要将defaultdict(int)的int参数更改为返回小于最小可能分数的数字的函数。

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

+0

+1为数据结构批评 – 2010-09-08 08:08:20

我会重新考虑数据结构,以满足您的需求更好地(对与分数作为值的列表名称散列例如字典),但我会做这样的:

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 

......怎么样

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