2015-07-09 2 views
-2

Учитывая следующий массив:Иерархическая суммирующий в питона

a = [] 
a.append({'c': 1, 'v': 10, 'p': 4}) 
a.append({'c': 2, 'v': 10, 'p': 4}) 
a.append({'c': 3, 'v': 10, 'p': None}) 
a.append({'c': 4, 'v': 0, 'p': None}) 
a.append({'c': 5, 'v': 10, 'p': 1}) 
a.append({'c': 6, 'v': 10, 'p': 1}) 

где с = код, v = значение и р = Родитель таблица выглядит следующим образом:

c v p 
1  4 
2 10 4 
3 10 
4 
5 10 1 
6 10 1 

Я должен суммировать каждый родитель со значениями это дети Ожидаемый результат таблица будет:

c v p 
1 20 4 
2 10 4 
3 10 
4 30 
5 10 1 
6 10 1 

Как это сделать?

+0

Нет, ожидаемый результат для 4 равен 30, как 1 является родительским 5 и 6 (так он суммируется до 20. 4 является родительским для 1 и 2. Поскольку 1 представляет собой сумму 5 и 6 + 2 (у которой значение 10, поэтому 10 + 10 + 10 = 30 – Gabor

+0

Извините, моя ошибка. быть несогласованностью в вашем примере. В коде '1' имеет значение' 10', но в таблице оно имеет значение '0' –

+0

True. Вы правы. Фактически таблица является валидной. – Gabor

ответ

0

Во-первых, вы должны получить другой словарь, сопоставляя родителей с списками своих детей, а не детей с родителями. Вы можете использовать для этого collections.defaultdict.

from collections import defaultdict 
children = defaultdict(list) 
for d in a: 
    children[d["p"]].append(d["c"]) 

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

values = {} 
for d in a: 
    values[d["c"]] = d["v"] 

Теперь вы можете очень легко определить рекурсивную функцию для вычисления общей стоимости. Обратите внимание, однако, что это сделает некоторые избыточные вычисления. Если ваши данные намного больше, вы можете обойти это, используя немного воспоминаний.

def total_value(x): 
    v = values[x] 
    for c in children[x]: 
     v += total_value(c) 
    return v 

Наконец, используя эту функцию в Словаре понимания дает суммарные значения для каждого кода:

>>> {x: total_value(x) for x in values} 
{1: 30, 2: 10, 3: 10, 4: 40, 5: 10, 6: 10} 
+0

Действительно, словарь уже (на самом деле это набор строк одного дерева). Давайте подумаем об учетной записи, в которой счета более высокого уровня суммируют значения нижнего уровня. Я не могу сказать, сколько детей у каждого родителя. Вот почему родительский код определен на уровне ребенка. Надеюсь, теперь я был чист. – Gabor

+0

@Gabor Нет, не слишком ясно, боюсь. Вы имели в виду, что вы не можете получить весь список детей для любого данного родителя? В этом случае, как бы вы получили общую стоимость? Вы пробовали, работает ли мой подход? Если нет, в чем проблема? –

+0

Мне нужно было время, чтобы понять ваше решение, но в конце концов я получил его. :-) Ваше решение дает правильный результат. Было бы более элегантно избегать этих дополнительных диктов, но пока это дает мне правильный результат, мне все равно. Благодарю. – Gabor

Смежные вопросы