简体   繁体   中英

How to convert list of list into structured dict, Python3

I have a list of list, the content of which should be read and store in a structured dictionary.

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

The 1st, 2nd, 3rd columns in each row represents 'id' , 'attr1' , 'attr2' . If 'id' in a row is not empty, a new object starts with this 'id' . In the example above, there are two objects. The object with 'id' being '1' has 3 elements in both 'attr1' and 'attr2' ; while the object with 'id' being '2' has 2 elements in both 'attr1' and 'attr2' . In my real application, there can be more objects, and each object can have an arbitrary number of elements.

For this particular example, the outcome should be

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

Could you please show me how to write a generic and efficient code to achieve it?

Thanks!

Just build the appropriate dict in a loop with the right conditions:

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)
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])

Not very beautiful code, could be a bit more concise.

Here's one solution using 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']]}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM