如何将列表列表转换为结构化dict,Python3

时间:2018-10-28 16:29:17

标签: python python-3.x list dictionary

我有一个列表清单,清单的内容应阅读并存储在结构化字典中。

my_list = [
    ['1', 'a1', 'b1'],
    ['',  'a2', 'b2'],
    ['',  'a3', 'b3'],
    ['2', 'c1', 'd1'],
    ['',  'c2', 'd2']]

每行的第一,第二,第三列代表'id''attr1''attr2'。如果一行中的'id'不为空,则新对象以此'id'开始。在上面的示例中,有两个对象。 'id''1'的对象在'attr1''attr2'中都有3个元素;而'id''2'的对象在'attr1''attr2'中都有2个元素。在我的实际应用程序中,可以有更多的对象,并且每个对象可以具有任意数量的元素。

对于此特定示例,结果应为

my_dict = {
    'id': ['1', '2'],
    'attr1': [['a1', 'a2', 'a3'], ['c1', 'c2']]
    'attr2': [['b1', 'b2', 'b3'], ['d1', 'd2']]

您能否告诉我如何编写通用且高效的代码来实现它?

谢谢!

3 个答案:

答案 0 :(得分:3)

只需在正确的条件下循环构建适当的dict

d = {f: [] for f in ('id', 'attr1', 'attr2')}

for id, attr1, attr2 in my_list:
    if id:
        d['id'].append(id)
        d['attr1'].append([])
        d['attr2'].append([])
    d['attr1'][-1].append(attr1)
    d['attr2'][-1].append(attr2)

答案 1 :(得分:1)

for i in my_list:
    if i[0] is not "":
        my_dict["id"].append(i[0])
        my_dict["attr1"].append([i[1]])
        my_dict["attr2"].append([i[2]])
    else:
        my_dict["attr1"][-1].append(i[1])
        my_dict["attr2"][-1].append(i[2])

代码不是很漂亮,可能会更简洁一些。

答案 2 :(得分:1)

这是使用collections.defaultdict的一种解决方案:

from collections import defaultdict

dd = defaultdict(lambda: defaultdict(list))

for num, attr1, attr2 in my_list:
    if num:
        current_id = num
    dd[current_id]['attr1'].append(attr1)
    dd[current_id]['attr2'].append(attr2)

# defaultdict(<function __main__.<lambda>()>,
#             {'1': defaultdict(list,
#                          {'attr1': ['a1', 'a2', 'a3'],
#                           'attr2': ['b1', 'b2', 'b3']}),
#              '2': defaultdict(list,
#                          {'attr1': ['c1', 'c2'], 'attr2': ['d1', 'd2']})})

attr1, attr2 = ([v[i] for v in dd.values()] for i in ('attr1', 'attr2'))

res = {'id': list(dd), 'attr1': attr1, 'attr2': attr2}

print(res)

{'id': ['1', '2'],
 'attr1': [['a1', 'a2', 'a3'], ['c1', 'c2']],
 'attr2': [['b1', 'b2', 'b3'], ['d1', 'd2']]}