You get an error because your syntax is wrong. The following appends to the list value for the 'Numbers' key:
myDict['Numbers'].append(user_inputs)
You can nest Python objects arbitrarily; your myDict2 syntax is entirely correct. Only the keys need to be immutable (so a tuple vs. a list), but your keys are all strings:
>>> myDict2 = {'Names': [{'first name':[],'Second name':[]}]}
>>> myDict2['Names']
[{'first name': [], 'Second name': []}]
>>> myDict2['Names'][0]
{'first name': [], 'Second name': []}
>>> myDict2['Names'][0]['first name']
[]
Answer from Martijn Pieters on Stack OverflowYou get an error because your syntax is wrong. The following appends to the list value for the 'Numbers' key:
myDict['Numbers'].append(user_inputs)
You can nest Python objects arbitrarily; your myDict2 syntax is entirely correct. Only the keys need to be immutable (so a tuple vs. a list), but your keys are all strings:
>>> myDict2 = {'Names': [{'first name':[],'Second name':[]}]}
>>> myDict2['Names']
[{'first name': [], 'Second name': []}]
>>> myDict2['Names'][0]
{'first name': [], 'Second name': []}
>>> myDict2['Names'][0]['first name']
[]
You should access the list with myDict['Numbers']:
>>>myDict['Numbers'].append(user_inputs)
You can have dicts inside of a list.
The only catch is that dictionary keys have to be immutable, so you can't have dicts or lists as keys.
How to create a nested dictionary from a list in Python? - Stack Overflow
How to walk through a nested dictionary with it's keys in a list?
python - Nested list to dict - Stack Overflow
How to Convert Nested List into dictionary in Python where lst[0][0] is the key - Stack Overflow
Videos
This easiest way is to build the dictionary starting from the inside out:
Copytree_dict = {}
for key in reversed(tree_list):
tree_dict = {key: tree_dict}
With an arbitrary terminal value:
Copyresult = ... # terminal value
for k in reversed(keys):
result = {k: result}
# result is the nested dict
Using a recursive function:
Copytree_list = ['Parents', 'Children', 'GrandChildren']
def build_tree(tree_list):
if tree_list:
return {tree_list[0]: build_tree(tree_list[1:])}
return {}
build_tree(tree_list)
Let's say I have a list
L = ['product', 'item', 'serial_key']
And a dictionary
D = {'product' : {'item' : {'serial_key' : None}, ...},
}
I basically want something like this:
D[L[0]][L[1]][L[2]]
I want to walk through the dictionary with the above list. It seems easy enough to do it with a for loop but this problem is surprisingly hard for me. How do I accomplish this?
What about:
d = {k:row[0] for row in groups for k in row[1:]}
This gives:
>>> {k:row[0] for row in groups for k in row[1:]}
{'D': 'Group2', 'B': 'Group1', 'C': 'Group2', 'A': 'Group1'}
So you iterate over every row in the groups. The first element of the row is taken as value (row[0]) and you iterate over row[1:] to obtain all the keys k.
Weird as it might seem, this expression also works when you give it an empty row (like groups = [[],['A','B']]). That is because row[1:] will be empty and thus the row[0] part is never evaluated:
>>> groups = [[],['A','B']]
>>> {k:row[0] for row in groups for k in row[1:]}
{'B': 'A'}
I think one line solution is a bit confusion. I would write code like below
groups = [['Group1', 'A', 'B'], ['Group2', 'C', 'D']]
result = {}
for group in groups:
for item in group[1:]:
result[item] = group[0]
print result
Use reduce() to traverse the dictionary:
Copyfrom functools import reduce # forward compatibility for Python 3
import operator
def getFromDict(dataDict, mapList):
return reduce(operator.getitem, mapList, dataDict)
and reuse getFromDict to find the location to store the value for setInDict():
Copydef setInDict(dataDict, mapList, value):
getFromDict(dataDict, mapList[:-1])[mapList[-1]] = value
All but the last element in mapList is needed to find the 'parent' dictionary to add the value to, then use the last element to set the value to the right key.
Demo:
Copy>>> getFromDict(dataDict, ["a", "r"])
1
>>> getFromDict(dataDict, ["b", "v", "y"])
2
>>> setInDict(dataDict, ["b", "v", "w"], 4)
>>> import pprint
>>> pprint.pprint(dataDict)
{'a': {'r': 1, 's': 2, 't': 3},
'b': {'u': 1, 'v': {'w': 4, 'x': 1, 'y': 2, 'z': 3}, 'w': 3}}
Note that the Python PEP8 style guide prescribes snake_case names for functions. The above works equally well for lists or a mix of dictionaries and lists, so the names should really be get_by_path() and set_by_path():
Copyfrom functools import reduce # forward compatibility for Python 3
import operator
def get_by_path(root, items):
"""Access a nested object in root by item sequence."""
return reduce(operator.getitem, items, root)
def set_by_path(root, items, value):
"""Set a value in a nested object in root by item sequence."""
get_by_path(root, items[:-1])[items[-1]] = value
And for completion's sake, a function to delete a key:
Copydef del_by_path(root, items):
"""Delete a key-value in a nested object in root by item sequence."""
del get_by_path(root, items[:-1])[items[-1]]
It seems more pythonic to use a for loop.
See the quote from Whatโs New In Python 3.0.
Removed
reduce(). Usefunctools.reduce()if you really need it; however, 99 percent of the time an explicitforloop is more readable.
Copydef nested_get(dic, keys):
for key in keys:
dic = dic[key]
return dic
def nested_set(dic, keys, value):
for key in keys[:-1]:
dic = dic.setdefault(key, {})
dic[keys[-1]] = value
def nested_del(dic, keys):
for key in keys[:-1]:
dic = dic[key]
del dic[keys[-1]]
Note that the accepted solution doesn't set non-existing nested keys (it raises KeyError). Using the approach above will create non-existing nodes instead.
The code works in both Python 2 and 3.