计算列表中相同索引的平均值,Python

3

我有一个如下所示的列表:

A= [('1', 3), ('2', 7), ('3', 5), ('1', 7), ('2', 5), ('3', 1)]

我想要从列表A生成如下输出列表:

Average = [('1', 5), ('2', 6), ('3', 2)]

任何技巧都将非常感激!=)

2
你怎么计算“3”键的平均值? - Cédric Julien
@Cédric:我想这是一个打字错误。任何其他值确实是平均值。 - Felix Kling
4个回答

2
from collections import defaultdict
a = [('1', 3), ('2', 7), ('3', 5), ('1', 7), ('2', 5), ('3', 1)]
d = defaultdict(list)
for k, v in a:
    d[k].append(v)
avg = [(k, sum(v) // len(v)) for k, v in d.iteritems()]
print avg

打印

[('1', 5), ('3', 3), ('2', 6)]

请注意,这里使用整数除法来计算平均值。你可能希望改用浮点除法。

非常感谢您的提示! :) 是的,我正在考虑如何在这里使用浮点除法.... 有什么建议吗? 再次感谢! :) - maria
@maria:使用sum(v, 0.0) / len(v)代替sum(v) // len(v) - Sven Marnach
@ Sven:我可以再问你一个问题吗?当我将浮点数作为值时,它不起作用。例如,>>> print result {'1': [3.2, 7.3, 4.2], '3': [5.2, 1.6, 6.3], '2': [7.7, 5.1, 2.5]} >>> avg = [(k, sum(v, 0.0) / len(v)) for k, v, in result.iteritems()] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'float' object is not callable - maria
@maria:无法重现错误--似乎工作正常。(请点击链接。)也许您将内置的sum()函数覆盖为同名变量了? - Sven Marnach
明白了。由于不同的Python版本,它在一个服务器上无法正常工作,而在另一个服务器上可以正常工作。非常感谢您出色的帮助,Sven! :D - maria

1
以简单的方式来说:
result = {}
for key, value in A:
   result.setdefault(key, []).append(value)

print [(k, sum(v) // len(v) for k,v in result.iteritems()]

如果您总是使用setdefault,那么defaultdict绝对是最好的选择。 - agf
1
@agf:我不同意。在这种情况下,两个版本的代码可读性相同,而且这个版本更短更快。 - Sven Marnach
@agf:没错,假设我兼容Python2.4及更早版本 ;) - Cédric Julien

0
你喜欢抽象代码和重复使用模式吗?如果是这样,那么这个group函数是你工具箱中有用的模式。它类似于itertools.groupby,但它可以处理非连续元素并在单次迭代中进行分类/映射(感谢Ruby Facets的map_by提供的思路):
def group(seq, callback=None):
    result = {}
    for category, item in (callback(seq) if callback else seq):
        result.setdefault(category, []).append(item)
    return result 

average = dict((k, sum(vs)/len(vs)) for (k, vs) in group(xs).items())
print(average)
# {'1': 5.0, '3': 3.0, '2': 6.0}

-1

一行代码。

a= [('1', 3), ('2', 7), ('3', 5), ('1', 7), ('2', 5), ('3', 1)]
map(lambda f:(f[0][0], (lambda g:sum(g)/len(g))(f[1])), map(lambda e:zip(*e), map(lambda c:filter(lambda d:d[0]==c, a), set(map(lambda b:b[0], a)))))

你的代码很聪明,我相信写起来很有趣,但是你因为陷入了一行代码症候群而得到了-1分。此外,这段代码对许多人来说将是晦涩难懂的,并且效率非常低下。 - Steven Rumbalski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接