Python - 根据内部列表的第一个元素,对列表中的元素进行求和

3

我有一个列表

[[0.5, 2], [0.5, 5], [2, 3], [2, 6], [2, 0.6], [7, 1]]

我需要对每个唯一的第一个元素的子列表中第二个元素求和并输出结果。在此示例中,输出为:

[[0.5, 7], [2, 9.6], [7, 1]]

这里的[0.5, 7]是将[0.5, 2][0.5, 5]的第二个元素相加。

如果要对长度为1,000的列表进行操作,最有效的方法是什么?


1
你能使用pandas或numpy吗?在这里,groupby是最好的选择,它基本上就是你所要求的。如果你以前从未编写过自己的groupby函数,那么这将是一个巨大的痛苦。 - Jamie Marshall
你的输入列表按第一个元素排序了吗? - jpp
长度为1000的列表很小。对于这种情况,使用pandas/numpy groupy会相当浪费。 - wim
@jpp 没有排序,但我想保留输出中的相同顺序。 - AndrewK
2
@AndrewK,我建议使用collections.defaultdict,它具有O(n)复杂度,并避免了Pandas / NumPy在您处理的小数组中的开销。 - jpp
@JamieMarshall 我可以使用,但是我想保持简单。我还没有使用过groupby,但现在我会去了解一下它。 - AndrewK
4个回答

4

使用defaultdict进行累加:

>>> from collections import defaultdict
>>> data = defaultdict(int)
>>> L = [[0.5, 2], [0.5, 5], [2, 3], [2, 6], [2, 0.6], [7, 1]]
>>> for k, v in L:
...     data[k] += v
...     
>>> [[k,v] for (k,v) in data.items()]
[[0.5, 7], [2, 9.6], [7, 1]]

请注意,由于加法运算,2的值被自动“提升”为浮点数,即使这是一个int类型的defaultdict。这是为了匹配问题中发布的所需输出,但我认为您应该考虑使用同质的输出类型,而不是int和float的混合。

谢谢。我不使用defaultdict。那么我该如何将其转换为一个列表,并保持与原始顺序相同? - AndrewK
为了保留在Python 3.6之前的原始顺序,请使用带有setdefault的OrderedDict。 - Mad Physicist
你有没有好的理由在意元素是列表还是元组..? - wim
@wim 可变性? - Mad Physicist
其实不是,但我对Python还很陌生,我以为列表执行append和delete等函数会更快。 - AndrewK
显示剩余6条评论

1
使用Pandas,您可以保留数据的原始“顺序”:
pairs = [[0.5, 2], [0.5, 5], [2, 3], [2, 6], [2, 0.6], [7, 1]]
df = pd.DataFrame(pairs)
>>> [tup[0] for tup in zip(df.groupby(0, sort=False, as_index=False).sum().values.tolist())]
[[0.5, 7.0], [2.0, 9.6], [7.0, 1.0]]

1

您可以使用排序和itertools.groupby来完成:

from operator import itemgetter
from itertools import groupby

data = [[0.5, 2], [0.5, 5], [2, 3], [2, 6], [2, 0.6], [7, 1]]

key = itemgetter(0)
data.sort(key=key)  # Use data = sorted(data, key=key) to avoid clobbering
result = [[k, sum(group)] for k, group in groupby(data, key)]

这将不保留键的原始顺序。

1
这会起作用吗?
L = [[0.5, 2], [0.5, 5], [2, 3], [2, 6], [2, 0.6], [7, 1]]
nums = []
d = {}
for lst in L:
    if lst[0] not in d:
        d[lst[0]] = []
        nums.append(lst[0])
    d[lst[0]].append(lst[1])

for key in nums:
    print [key, sum(d[key])]

输出:

[0.5, 7]
[2, 9.6]
[7, 1]

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