I have a multi key dict in the following format. I am trying to access the list of the second level keys, however, it is returning the keys in the format of a dict_keys list. What I am trying to get is ['a', 'b', 'c', 'd', 'e', 'f']
dictTest={}
dictTest[1]={'a':1, 'b':2}
dictTest[2]={'c':1, 'd':2}
dictTest[3]={'e':1, 'f':2}
print(dictTest)
print(list([dictTest[i].keys() for i in dictTest.keys()]))
{1: {'a': 1, 'b': 2}, 2: {'c': 1, 'd': 2}, 3: {'e': 1, 'f': 2}}
[dict_keys(['a', 'b']), dict_keys(['c', 'd']), dict_keys(['e', 'f'])]
You could use itertools.chain in combination with mapping dict.keys to all the dicts values:
from itertools import chain
dictTest = {1: {'a': 1, 'b': 2}, 2: {'c': 1, 'd': 2}, 3: {'e': 1, 'f': 2}}
print(list(chain(*map(dict.keys, dictTest.values()))))
['a', 'b', 'c', 'd', 'e', 'f']
>>> [v2 for v1 in dictTest.values() for v2 in v1]
['a', 'b', 'c', 'd', 'e', 'f']
Try this:
# sum([list(b.keys()) for b in dictTest.values()], [])
# syntax improvement by #wwii
sum([list(b) for b in dictTest.values()], [])
Output:
['a', 'b', 'c', 'd', 'e', 'f']
If key 'a' has a value of 'c' then the key of 'c' should append 'a'. Please note that that the values associated with key 'a' are not included in the append.
I cant seem to figure out how to automate this process to perform on a large dictionary.
mydict = {
'a': ['z', 'c'],
'b': ['y', 'c'],
'c': ['q', 'r']
}
Here is my desired result :
mydict = {
'a': ['z', 'c'],
'b': ['y', 'c'],
'c': ['q', 'r', 'a', 'b']
}
Here is another way to do this, using set intersections, as well as keeping an intermediate mapping of parent/children relationships.
from collections import defaultdict
d = defaultdict(list)
keys = set([*mydict])
for k, v in mydict.items():
intersected = keys & set(v)
for i in intersected:
d[i].append(k)
print(d)
# defaultdict(list, {'c': ['b', 'a']})
for found, value in d.items():
mydict[found].extend(value)
print(mydict)
# {'a': ['z', 'c'], 'b': ['y', 'c'], 'c': ['q', 'r', 'b', 'a']}
for k in mydict:
for val in mydict[k]:
if val in mydict:
mydict[val] += [k]
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': []}
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': []})
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.
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
}
>>>
G2 = {'a': {'c': 1, 'b': 1}, 'b': {'a': 1, 'c': 1}}
b = G2.values()
for i in b:
for key, value in i.items():
list.append(key)
#result: ['c', 'b', 'a', 'c']
Can I get the same result but using a list generator?
I tried it like this:
list2 = [key for key, value in i.items() for i in b]
#but i get: ['a', 'a', 'c', 'c']
just chain the dictionary values (aka keys) using itertools.chain.from_iterable, and convert to list to print the result:
import itertools
G2 = {'a': {'c': 1, 'b': 1}, 'b': {'a': 1, 'c': 1}}
#['c', 'b', 'a', 'c']
result = list(itertools.chain.from_iterable(G2.values()))
print(result)
result:
['c', 'b', 'c', 'a']
note that the order is not guaranteed as you're iterating on dictionary keys.
Variant without using itertools with flattening double loop inside comprehension (which is probably closer to your attempt):
result = [x for values in G2.values() for x in values]