Python 如何汇总具有相同第一个元素的元组列表?
我有一个元组列表,例如:Python 如何汇总具有相同第一个元素的元组列表?,python,list,Python,List,我有一个元组列表,例如: (1,3) (1,2) (1,7) (2,4) (2,10) (3,8) 我需要能够根据第一个值是什么来总结第二个值,得到示例列表的结果: (1,12) (2,14) (3,8) 这个问题本质上非常类似于,但是,我的解决方案可能不使用任何导入或for循环,并且该问题的所有答案都使用其中一个。它应该依赖于列表和集合理解 my_set = {x[0] for x in my_tuples} my_s
(1,3)
(1,2)
(1,7)
(2,4)
(2,10)
(3,8)
我需要能够根据第一个值是什么来总结第二个值,得到示例列表的结果:
(1,12)
(2,14)
(3,8)
这个问题本质上非常类似于,但是,我的解决方案可能不使用任何导入或for循环,并且该问题的所有答案都使用其中一个。它应该依赖于列表和集合理解
my_set = {x[0] for x in my_tuples}
my_sums = [(i,sum(x[1] for x in my_tuples if x[0] == i)) for i in my_set]
我想。。。对于这个问题,这些要求不是很好(这个解决方案会很慢…如果您使用的是python2,您可以使用map来表现得像
izip_longest
一样,并获取组结束的索引:
def sums(l):
st = set()
inds = [st.add(a) or ind for ind, (a, b) in enumerate(l) if a not in st]
return [(l[i][0], sum(sub[1] for sub in l[i:j])) for i, j in map(None, inds, inds[1:])]
输出:
In [10]: print(sums(l))
[(1, 12), (2, 14), (3, 8)]
对于python 2或3,您只需使用enumerate并检查索引:
def sums(l):
st = set()
inds = [st.add(a) or ind for ind, (a, b) in enumerate(l) if a not in st]
return [(l[j][0], sum(sub[1] for sub in (l[j:inds[i]] if i < len(inds) else l[inds[-1]:])))
for i, j in enumerate(inds, 1)]
如果你能使用字典,下面的方法应该可以
x = [(1,3), (1, 2), (1, 7), (2, 4), (2, 10), (3, 8)]
d = {}
[d.__setitem__(first, d.get(first, 0) + second) for first, second in x]
print(list(d.items()))
这非常简单,但绝对是O(n**2),因此请保持输入数据较小:
data = (
(1,3),
(1,2),
(1,7),
(2,4),
(2,10),
(3,8),
)
d = { k:v for k,v in data }
d2 = [(t1,sum( v for k,v in data if k == t1 )) for t1 in d.keys() ]
print(d2)
输出为
[(1, 12), (2, 14), (3, 8)]
我会用默认的dict
from collections import defaultdict
x = [(1,3), (1, 2), (1, 7), (2, 4), (2, 10), (3, 8)]
d = defaultdict(int)
for k, v in x:
d[k] += v
print(list(d.items()))
如果您需要使用itertools的单行程序(lambda内联函数)
from itertools import groupby
myfunc = lambda tu : [(k, sum(v2[1] for v2 in v)) for k, v in groupby(tu, lambda x: x[0])])
print(myfunc(x))
你们自己试过什么吗?“这应该依赖于列表和设置理解。”-那就糟糕了。理解是有用的,但对于这样的操作来说,理解是错误的工具。基于理解的自然解决方案需要二次时间。这可能是python课程“理解”部分的一个家庭作业问题。Paul Rooney,我最初的想法是使用一个映射和键结构,就像我在java中编程时使用的那样,迭代列表以求和到正确的键,但是使用for循环的限制极大地阻碍了我的选择。我也考虑过使用Joran Beasley的答案,但我想知道是否有任何方法可以不使用二次时间来实现这一点。在这种情况下,这是一个糟糕的家庭作业问题(或者更糟糕的面试问题…)。。。在很多地方,理解是很有意义的。。。这不是一个这样的senario,您可以使用直接的集合comprensoin(
{x[0]…}
)而不是生成器表达式和集合
内置。
from itertools import groupby
myfunc = lambda tu : [(k, sum(v2[1] for v2 in v)) for k, v in groupby(tu, lambda x: x[0])])
print(myfunc(x))