2016-09-22 2 views
0

У меня есть большой набор данных, отформатированных как d.items()defaultdict(list). Смотрите ниже:Сопоставление сумм defaultdict (списка) с одним списком

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 не уверен, является ли правильным инструментом, чтобы сделать мое задание.

ответ

3

Из того, что я понимаю, что вам нужно почтовый подсписков в списке и просуммировать их:

>>> 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 и хороший список literal- распаковывать:

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]