【问题标题】:Mapping sums of defaultdict(list) to one list将 defaultdict(list) 的总和映射到一个列表
【发布时间】:2017-01-31 09:36:27
【问题描述】:

我有大量数据的格式有点像defaultdict(list)d.items()。见下文:

products = [(('blue'), ([2, 4, 2, 4, 2, 4, 2, 4, 2, 4], [2, 4, 2, 4, 2, 4, 2, 4, 2, 4], [2, 4, 2, 4, 2, 4, 2, 4, 2, 4])),
        (('yellow'), ([1, 3, 1, 3, 1, 3, 1, 3, 1, 3], [1, 3, 1, 3, 1, 3, 1, 3, 1, 3], [1, 3, 1, 3, 1, 3, 1, 3, 1, 3])),
        (('red'), ([1, 1, 1, 1, 1, 2, 5, 4, 6, 4], [2, 5, 3, 4, 8, 1, 1, 1, 1, 1], [8, 6, 3, 9, 2, 1, 1, 1, 1, 1]))]

我想将嵌套列表中每个数据值的总和映射到它们在相同位置或索引中的对应对应项,以产生如下的最终总和:

['blue', 6, 12, 6, 12, 6, 12, 6, 12, '6.000000', 12]
['yellow', 3, 9, 3, 9, 3, 9, 3, 9, '3.000000', 9]
['red', 11, 12, 7, 14, 11, 4, 7, 6, '8.000000', 6]

使用循环,可以很容易地做到这一点,如下函数所示:

def summation(products):

    sums = []

    for item in products:
            sums.append([(item[0]),
                     sum(int(x[0]) for x in item[1]),
                     sum(int(x[1]) for x in item[1]),
                     sum(int(x[2]) for x in item[1]),
                     sum(int(x[3]) for x in item[1]),
                     sum(int(x[4]) for x in item[1]),
                     sum(int(x[5]) for x in item[1]),
                     sum(int(x[6]) for x in item[1]),
                     sum(int(x[7]) for x in item[1]),
                     "{:.6f}".format(sum(float(x[8]) for x in item[1])),
                     sum(int(x[9]) for x in item[1])])

    for s in sums:
        print(s)

当产品的规模为数百万时,就会出现问题,即非常耗时。所以我想实现将每个值映射到嵌套列表中相同键的对应值。这是我尝试过的:

def mappingSum(products):
    sums = []

    for item in products:
        sums.append([item[0], map((sum(x), sum(y), sum(z)) for x, y, z in item[1])])



    for s in sums:
        print(s)

但是,我收到以下错误:

TypeError: map() must have at least two arguments.

我不知道如何解决它,我不确定map 是否是完成我任务的正确工具。

【问题讨论】:

    标签: python list python-3.x mapping defaultdict


    【解决方案1】:

    据我了解,您需要压缩列表中的子列表并总结它们:

    >>> sums = [(key, [sum(value) for value in zip(*values)]) for key, values in products]
    >>> for s in sums:
    ...     print(s)
    ... 
    ('blue', [6, 12, 6, 12, 6, 12, 6, 12, 6, 12])
    ('yellow', [3, 9, 3, 9, 3, 9, 3, 9, 3, 9])
    ('red', [11, 12, 7, 14, 11, 4, 7, 6, 8, 6])
    

    【讨论】:

      【解决方案2】:

      作为@alecxe 的答案的替代方案,请考虑使用map 和一个不错的列表文字解包:

      res = [(k, [*map(sum, zip(*v))]) for k, v in products]
      

      这会产生:

      [('blue', [6, 12, 6, 12, 6, 12, 6, 12, 6, 12]),
       ('yellow', [3, 9, 3, 9, 3, 9, 3, 9, 3, 9]),
       ('red', [11, 12, 7, 14, 11, 4, 7, 6, 8, 6])]
      

      这稍微快一点,但由于文字解包,需要 Python >= 3.5。如果在早期版本中,您必须将其包装在 list 调用中以解压缩 map 迭代器:

      res = [(k, list(map(sum, zip(*v)))) for k, v in products]
      

      【讨论】:

        猜你喜欢
        • 2014-12-12
        • 2016-01-11
        • 1970-01-01
        • 2019-06-24
        • 2018-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-19
        相关资源
        最近更新 更多