Python 如何在元组列表中找到每个相似项的平均值?

Python 如何在元组列表中找到每个相似项的平均值?,python,list,tuples,Python,List,Tuples,我有这个元组列表 [('Jem', 10), ('Sam', 10), ('Sam', 2), ('Jem', 9), ('Jem', 10)] 如何找到与每个名称耦合的数字的平均值,即使用Jem存储在元组中的所有数字的平均值,然后输出它们?在本例中,输出为: Jem 9.66666666667 Sam 6 似乎是集合的直接例子。defaultdict from collections import defaultdict l = [('Jem', 10), ('Sam', 10), ('S

我有这个元组列表

[('Jem', 10), ('Sam', 10), ('Sam', 2), ('Jem', 9), ('Jem', 10)]
如何找到与每个名称耦合的数字的平均值,即使用Jem存储在元组中的所有数字的平均值,然后输出它们?在本例中,输出为:

Jem 9.66666666667
Sam 6

似乎是
集合的直接例子。defaultdict

from collections import defaultdict
l = [('Jem', 10), ('Sam', 10), ('Sam', 2), ('Jem', 9), ('Jem', 10)]
d = defaultdict(list)
for key, value in l:
    d[key].append(value)
然后计算平均值

from numpy import mean
for key in d:
    print(key, mean(d[key]))
输出

Jem 9.66666666667
Sam 6.0

有几种方法可以做到这一点。一个简单,一个漂亮

容易的: 使用字典!很容易为构建一个循环,该循环遍历元组并将第二个元素附加到字典中,并键入第一个元素

d = {}
tuples = [('Jem', 10), ('Sam', 10), ('Sam', 2), ('Jem', 9), ('Jem', 10)]
for tuple in tuples:
    key,val = tuple
    d.setdefault(key, []).append(val)
一旦它出现在字典中,您可以执行以下操作:

for name, values in d.items():
    print("{name} {avg}".format(name=name, avg=sum(values)/len(values)))
漂亮的: 使用
itertools.groupby
。仅当数据按要分组的键排序时(在本例中,
t[0]
用于
tuples
中的每个
t
),这才有效,因此在这种情况下并不理想,但这是突出显示函数的一种好方法

from itertools import groupby

tuples = [('Jem', 10), ('Sam', 10), ('Sam', 2), ('Jem', 9), ('Jem', 10)]
tuples.sort(key=lambda tup: tup[0])
# tuples is now [('Jem', 10), ('Jem', 9), ('Jem', 10), ('Sam', 10), ('Sam', 2)]

groups = groupby(tuples, lambda tup: tup[0])
这构建了一个类似于以下内容的结构:

[('Jem', [('Jem', 10), ('Jem', 9), ('Jem', 10)]),
 ('Sam', [('Sam', 10), ('Sam', 2)])]
我们可以用它来建立我们的名字和平均数:

for groupname, grouptuples in groups:
    values = [t[1] for t in groupvalues]
    print("{name} {avg}".format(name=groupname, avg=sum(values)/len(values)))

您还可以使用列表理解:

l = [('Jem', 10), ('Sam', 10), ('Sam', 2), ('Jem', 9), ('Jem', 10)]

def avg(l):
    return sum(l)/len(l)

result = [(n, avg([v[1] for v in l if v[0] is n])) for n in set([n[0] for n in l])]
# result is [('Jem', 9.666666666666666), ('Sam', 6.0)]

您使用
key=lambda tup:tup[0]
进行排序有什么原因吗?@Finn在这种特定情况下,这是不必要的,因为
tuple
默认情况下会按第一个元素进行排序。但我猜他们把它放在那里是为了处理一般情况,如果你想按其他元素排序的话。显式比隐式好。没有其他原因——我知道元组以这种方式自然排序,但它确实更清晰地突出了排序序列和按序列的组成元素对序列进行分组之间的相似之处。
from collections import defaultdict;d=默认DICT(列表);图(λk,v:d[k].附加(v),l);[(k,sum(v)/len(v))表示k,v在d中。items()]
一行程序并不总是最好的:)@AdamSmith那么如何在单独的行中编写列表理解呢?你没有,这是我的观点!)我认为这种情况不适合列表公司。也就是说,我刚刚注意到如果v[0]==n,你应该做
,而不是
如果v[0]是n
。你在比较平等而不是身份!谢谢你指出这一点。我想如果我测试的对象是不可变的,那么使用identity是更好的解决方案?两个不可变对象可能没有相同的identity。Python可能会缓存对象并重用它,但这是一个实现问题<代码>a=10e12;b=10e12;当
c=1时,a为b
wil失败;d=1;c是d
将成功。