简体   繁体   中英

How to create a dictionary of dictionaries using a list of lists and a list of tuples

I would like to create the dictionary Result using a list of lists (distance) and a list of tuples (routes). What can I do to obtain the Result dictionary?

distance = [['167724.1407', '151859.5908', '150131.7254'],
            ['186216.5193', '170351.9694', '168624.1039']]


routes = [('A', 'ind1'), ('A', 'ind2'), ('A', 'ind3'),
          ('B', 'ind1'), ('B', 'ind2'), ('B', 'ind3')]


Result = {'A': {'ind1': '167724.1407', 'ind2': '151859.5908', 'ind3': '150131.7254' },
          'B': {'ind1': '186216.5193', 'ind2': '170351.9694', 'ind3': '168624.1039' }}

[edit] I'm solving a linear programming problem with PULP, so A and B are the names of Warehouses and ind1, ind2, ind3 are the names of stores.

I've flattened the distance list in order to make it easy and used defaultdicct to update existing dictionary to contain new values.

from collections import defaultdict

distance = [
    ["167724.1407", "151859.5908", "150131.7254"],
    ["186216.5193", "170351.9694", "168624.1039"],
]


routes = [
    ("A", "ind1"),
    ("A", "ind2"),
    ("A", "ind3"),
    ("B", "ind1"),
    ("B", "ind2"),
    ("B", "ind3"),
]

flat_distance = [d for sublist in distance for d in sublist]


result = defaultdict(dict)

for index, route in enumerate(routes):
    result[route[0]].update({route[1]: flat_distance[index]})
    
result = dict(result)  # converting defaultdict back to dict

Output:

{'A': {'ind1': '167724.1407', 'ind2': '151859.5908', 'ind3': '150131.7254'}, 'B': {'ind1': '186216.5193', 'ind2': '170351.9694', 'ind3': '168624.1039'}}

please use data structure:

distance = [['167724.1407', '151859.5908', '150131.7254'], ['186216.5193', '170351.9694', '168624.1039']] 

routes = [('A', 'ind1'), ('A', 'ind2'), ('A', 'ind3'), ('B', 'ind1'), ('B', 'ind2'), ('B', 'ind3')]

index_dict = {} # e.g. A : 0, B : 1,  helper dictionalry

result = {} # final dictionaly

index = 0

for key, inside_key in routes:

    if index_dict.get(key) == None:
        index_dict[key] = index # save index of dict value of routes, so you can get respective distance value list
        index = index + 1
    
    if result.get(key) == None:
        result[key] = {} # initialize dict for e.g. A : {}
    
    # finally store it in dictionary
    result[key][inside_key] = distance[index_dict[key]][len(result[key])]

print(result)

using above code you can achieve result:

{'A': {'ind1': '167724.1407', 'ind2': '151859.5908', 'ind3': '150131.7254'}, 'B': {'ind1': '186216.5193', 'ind2': '170351.9694', 'ind3': '168624.1039'}}

You can also use itertools , chain.from_iterable + zip

from itertools import chain

result = {}

for (a,b), d in zip(routes, chain.from_iterable(distance)):
    result.setdefault(a, {}).update({b: d})

{'A': {'ind1': '167724.1407', 'ind2': '151859.5908', 'ind3': '150131.7254'}, 
'B': {'ind1': '186216.5193', 'ind2': '170351.9694', 'ind3': '168624.1039'}}

If you are a nutter for list comprehensions, then this 2 line code might interest you:)

from collections import defaultdict 
from operator import itemgetter 
from itertools import groupby 

kk = dict((k, [v[1] for v in itr]) for k, itr in groupby(routes, itemgetter(0)))
out = {list(kk.keys())[i]:dict(zip(list(kk.values())[i],distance[i])) for i in range(len(kk.keys()))}
print(out)
'A': {'ind1': '167724.1407', 'ind2': '151859.5908', 'ind3': '150131.7254'},
'B': {'ind1': '186216.5193', 'ind2': '170351.9694', 'ind3': '168624.1039'}}

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