python - агрегированные данные в структуре вложенного списка - PullRequest
1 голос
/ 10 ноября 2019

У меня есть список с вложенным подсписком со следующей структурой

in_data = 
 [
   [
     ['name', 'name_1'],  
     ['item_B', '2'], 
     ['item_C', '3'], 
     ['item_D', '4']
   ],
   [
     ['name', 'name_2'], 
     ['item_B', '5'], 
     ['item_A', '2']
   ],
   [
     ['name', 'name_3'], 
     ['item_B', '6'], 
     ['item_C', '7']
   ]
]

Я пытаюсь собрать все данные в in_data и создать уникальный список, который содержит подсписки, один для всех "заголовков" / имен и один для каждого элемента + значения в правильном порядке. Таким образом, информация сохраняется, но в другой структуре данных.

Я хочу получить этот список :

res_list = 
[
  ['name', ' name_1', ' name_2', 'name_3'], 
  ['item_B', '2', '5', '6'], 
  ['item_C', '3','-', '7'], 
  ['item_D', '4','-', '-'], 
  ['item_A', '-','2', '-'] 
]

Я пытаюсь сделать это в большинствепитонический путь. Я пытался использовать циклы for, а также map () + lambda, но безуспешно.

было бы проще?

Ответы [ 2 ]

2 голосов
/ 10 ноября 2019

Оптимизированный подход (питание от комбинированных ключей dict (<skill name>, <column name>) и dict.get метод):

header = ['names']
names = set()
d = {}

for lst in in_data:
    col_name = lst[0][-1]
    header.append(col_name)
    for name, val in lst[1:]:
        names.add(name)
        d[name, col_name] = val

res = [[n, *[d.get((n, h), '-') for h in header[1:]]] for n in names]
res.insert(0, header)
print(res)

Выход:

[['names', 'name_1', 'name_2', 'name_3'],
 ['item_C', '3', '-', '7'],
 ['item_D', '4', '-', '-'],
 ['item_B', '2', '5', '6'],
 ['item_A', '-', '2', '-']]
1 голос
/ 10 ноября 2019

Вы можете использовать collections.defaultdict:

import collections
in_data = [[['name', 'name_1'], ['item_B', '2'], ['item_C', '3'], ['item_D', '4']], [['Skill', 'name_2'], ['item_B', '5'], ['item_A', '2']], [['Skill', 'name_3'], ['item_B', '6'], ['item_C', '7']]]
d = [list(zip(['name', *b[0][1:]], i)) for b in in_data for i in b[1:]]
new_d = collections.defaultdict(dict)
for i in d:
   new_d[dict(i)['name']][i[-1][0]] = i[-1][-1]

all_names = list({i for b in new_d.values() for i in b})[::-1]
result = [['name', *all_names], *[[a, *[b.get(k, '-') for k in all_names]] for a, b in new_d.items()]]

Выход:

[['name', 'name_1', 'name_2', 'name_3'], 
 ['item_B', '2', '5', '6'], 
 ['item_C', '3', '-', '7'], 
 ['item_D', '4', '-', '-'], 
 ['item_A', '-', '2', '-']]
...