代码之家  ›  专栏  ›  技术社区  ›  Dale Reidy

添加元组以生成每个“列”都有小计的元组

  •  2
  • Dale Reidy  · 技术社区  · 17 年前

    如:

    >>> a = (10, 20)
    >>> b = (40, 50)
    >>> c = (1, 3)
    >>> ???
    (51, 73)
    

    到目前为止,我考虑了以下几点:

    def sumtuples(*tuples):
        return (sum(v1 for v1,_ in tuples), sum(v2 for _,v2 in tuples))
    
    >>> print sumtuples(a, b, c)
    (51, 73)
    

    我确信这远非理想——如何改进?

    5 回复  |  直到 17 年前
        1
  •  6
  •   ars    17 年前

    我想你可以用 reduce

    In [13]: reduce(lambda s, t: (s[0]+t[0], s[1]+t[1]), [a, b, c], (0, 0))
    Out[13]: (51, 73)
    

    这是使用的另一种方法 map 和 zip :

    In [14]: map(sum, zip(a, b, c))
    Out[14]: [51, 73]
    

    或者,如果你将元组集合作为列表传递:

    In [15]: tups = [a, b, c]
    
    In [15]: map(sum, zip(*tups))
    Out[15]: [51, 73]
    

    并且,使用列表理解而不是 :

    In [16]: [sum(z) for z in zip(*tups)]
    Out[16]: [51, 73]
    
        2
  •  2
  •   user44484 user44484    17 年前

    既然我们快疯了,

    a = (10, 20)
    b = (40, 50)
    c = (1, 3)
    
    def sumtuples(*tuples):
       return map(sum, zip(*tuples))
    
    sumtuples(a,b,c)
    [51, 73]
    

    事实上,几乎每次我发布这些疯狂的解决方案时,“天真”的方法似乎都会更快、更易读。..

        3
  •  1
  •   wr.    17 年前

    from scipy import array
    a = array((10, 20))
    b = array((40, 50))
    c = array((1, 3))
    
    print tuple(a+b+c)
    
        4
  •  0
  •   Mark Roddy    17 年前

    >>> a = (10, 20)
    >>> b = (40, 50)
    >>> c = (1, 3)
    >>> values=[a,b,c]
    >>> reduce(lambda x,y: (x[0]+y[0],x[1]+y[1]), values,(0,0))
    (51, 73)
    
        5
  •  0
  •   Glenn Maynard    17 年前

    这些解决方案都存在以下两个问题之一:

    • 它们不适用于迭代器,因此生成十亿行不起作用(或浪费大量内存)。

    不要以得不到正确答案为代价而陷入“蟒蛇”的流行语。

    def sum_columns(it):
        result = []
        for row in it:
            if len(result) <= len(row):
                extend_by = len(row) - len(result)
                result.extend([0] * extend_by)
    
            for idx, val in enumerate(row):
                result[idx] += val
    
        return result
    
    a = (1, 20)
    b = (4, 50)
    c = (0, 30, 3)
    print sum_columns([a,b,c])
    
    def generate_rows():
        for i in range(1000):
            yield (i, 1, 2)
    
    lst = generate_rows()
    print sum_columns(lst)