Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何汇总具有相同第一个元素的元组列表?_Python_List - Fatal编程技术网

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