简体   繁体   中英

Converting list of lists to a dictionary with multiple values for a key

I need to write a function that accepts a list of lists representing friends for each person and need to convert it into a dictionary. so an input of [['A','B'],['A','C'],['A','D'],['B','A'],['C','B'],['C','D'],['D','B'],['E']] should return {A:[B,C,D],B:[A],C:[B,D],D:[B],E:None}

Input:

[['A','B'],['A','C'],['A','D'],['B','A'],['C','B'],['C','D'],['D','B'],['E']]

Expected Output:

{A:[B,C,D],B:[A],C:[B,D],D:[B],E:None}

Currently I am trying the following:

s=[['A','B'],['A','C'],['A','D'],['B','A'],['C','B'],['C','D'],['D','B'],['E']]

output=dict.fromkeys((set([x[0] for x in s])),[ ])

for x in s:
    if len(x)>1:
        output[x[0]].append(x[1])
    else:
        output[x[0]].append(None)

But the output is giving me all values for every key rather than returning only the corresponding values

The output i am getting is:

{
'A': ['B', 'C', 'D', 'A', 'B', 'D', 'B', None],

 'B': ['B', 'C', 'D', 'A', 'B', 'D', 'B', None],

 'C': ['B', 'C', 'D', 'A', 'B', 'D', 'B', None],

 'D': ['B', 'C', 'D', 'A', 'B', 'D', 'B', None],

 'E': ['B', 'C', 'D', 'A', 'B', 'D', 'B', None]
}

You can iterate through the key-value pairs in the list of lists, but unpack the value as a list to accommodate the possible lack of a value:

s = [['A','B'],['A','C'],['A','D'],['B','A'],['C','B'],['C','D'],['D','B'],['E']]
output = {}
for k, *v in s:
    if v:
        output.setdefault(k, []).extend(v)
    else:
        output[k] = None

output becomes:

{'A': ['B', 'C', 'D'], 'B': ['A'], 'C': ['B', 'D'], 'D': ['B'], 'E': None}

Or if you don't mind that keys without a value get an empty list instead of None , you can simply do:

output = {}
for k, *v in s:
    output.setdefault(k, []).extend(v)

output would then become:

{'A': ['B', 'C', 'D'], 'B': ['A'], 'C': ['B', 'D'], 'D': ['B'], 'E': []}

You should use a common dict comprehension to initiate the dict :

output = {x[0]: [] for x in s}

dict.fromkeys gives all keys the identical referential value. With a mutable value that is a problem. The comprehension will give each key an independent list object, in addition to being more readable.

The issue is the list you feed to dict.keys is only one reference across keys.

Your desired result is inconsistent. I recommend you choose an empty list for 'E' , however much it seems None is more appropriate. With this adjusted requirement, you can use collections.defaultdict .

from collections import defaultdict

L = [['A','B'],['E','C'],['A','D'],['B','A'],['C','B'],['C','D'],['D','B'],['E']]

dd = defaultdict(list)

for lst in L:
    if len(lst) > 1:
        dd[lst[0]].append(lst[1])
    else:
        dd[lst[0]]

print(dd)

defaultdict(list,
            {'A': ['B', 'C', 'D'],
             'B': ['A'],
             'C': ['B', 'D'],
             'D': ['B'],
             'E': []})

One of the way to solve this is as given below:

friend_combi = [['A','B'],['A','C'],['A','D'],['B','A'],['C','B'],['C','D'],['D','B'],['E']]  # Input to be processed

final_dict = {} #Empty dict to store result
for i in friend_combi: # loop through each element in list
    if final_dict.get(i[0]):  #if data present in dict then append else add
        final_dict[i[0]].append(i[1])
    else:
        final_dict[i[0]] = [i[1]] if i[1:] else None #check if value exist in list else save None
print (final_dict)
#Output --> {'A': ['B', 'C', 'D'], 'B': ['A'], 'C': ['B', 'D'], 'D': ['B'], 'E': None}

I hope this helps :)

You can define a function named get_dictionary() as the below code shows.

>>> def get_dictionary(l):
...     d = {}
...     for arr in l:
...         if len(arr) == 2:
...             key = arr[0]
...             if key in d:
...                 d[key].append(arr[1])
...             else:
...                 d[key] = [arr[1]]
...         else:
...             d[key] = None
...     return d
...
>>> l = [['A','B'], ['A','C'], ['A','D'], ['B','A'], ['C','B'], ['C','D'], ['D','B'], ['E']]
>>>
>>> get_dictionary(l)
{'A': ['B', 'C', 'D'], 'B': ['A'], 'C': ['B', 'D'], 'D': None}
>>>

Pretty printing the dictionary as JSON.

>>> import json
>>>
>>> d = get_dictionary(l)
>>>
>>> print(json.dumps(d, indent=4))
{
    "A": [
        "B",
        "C",
        "D"
    ],
    "B": [
        "A"
    ],
    "C": [
        "B",
        "D"
    ],
    "D": null
}
>>>

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