Python nested dictionary and nested update - python

I would like to update or create a nested dictionary without altering the existing content.
In the example below I will try to add the couple {'key2.2': 'value2.2'} nested as a child to the entry key2.
Case 1: the parent key (key2) exists :
mydict = {'key1': 'value1', 'key2': {'key2.1': 'value2.1'}}
mydict['key2'].update({'key2.2': 'value2.2'})
pprint(mydict)
{'key1': 'value1', 'key2': {'key2.1': 'value2.1', 'key2.2': 'value2.2'}}
This is what I expected, no problem here.
Case 2: the parent key (key2) does not exists :*
mydict = {'key1': 'value1'}
mydict['key2'].update({'key2.2': 'value2.2'})
KeyError: 'key2'
Seems logic, so let's try something else..
mydict = {'key1': 'value1'}
mydict.update({'key2': {'key2.2': 'value2.2'}})
pprint(mydict)
{'key1': 'value1', 'key2': {'key2.2': 'value2.2'}}
Perfect !
Let's check if this works with case 1 too.
Case 1B: the parent key (key2) exists :
mydict = {'key1': 'value1', 'key2': {'key2.1': 'value2.1'}}
mydict.update({'key2': {'key2.2': 'value2.2'}})
pprint(mydict)
{'key1': 'value1', 'key2': {'key2.2': 'value2.2'}}
The existing entry {'key2.1': 'value2.1'} got deleted, this is not what I want.
What would be the best way to achieve what I want ? Like a nested update ?
I know this would be possible with a couple of try:/except KeyError:, but it doesn't seems very clean.

You could use defaultdict:
from collections import defaultdict
mydict = defaultdict(dict)
mydict.update({'key1': 'value1', 'key2': {'key2.1': 'value2.1'}})
mydict['key2'].update({'key2.2': 'value2.2'})
print(mydict)
mydict = defaultdict(dict)
mydict.update({'key1': 'value1'})
mydict['key2'].update({'key2.2': 'value2.2'})
print(mydict)
Outputs:
defaultdict(<class 'dict'>, {'key1': 'value1', 'key2': {'key2.1': 'value2.1', 'key2.2': 'value2.2'}})
defaultdict(<class 'dict'>, {'key1': 'value1', 'key2': {'key2.2': 'value2.2'}})

Try:
mydict = {'key1': 'value1', 'key2': {'key2.1': 'value2.1'}}
if "key2" in mydict:
mydict["key2"].update({'key2.2': 'value2.2'})
else:
mydict["key2"] = {'key2.2': 'value2.2'}

Code:
mydict = {'key1': 'value1', 'key2': {'key2.1': 'value2.1'}}
mydict['key2.2'.split('.')[0]].update({'key2.2' : 'value2.2'})
print(mydict)
Output:
{'key2': {'key2.2': 'value2.2', 'key2.1': 'value2.1'}, 'key1': 'value1'}

Related

Split string of key=value into dictionary

I want to create a dictionary from a string that have key=value
s = "key1=value1 key2=value2 key3=value3"
print({r.split("=") for r in s})
Is it possible using dictionary comprehension? If yes, how?
You can first split on whitespace, then split on '='
>>> dict(tuple(i.split('=')) for i in s.split())
{'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
You could use map:
>>> s = "key1=value1 key2=value2 key3=value3"
>>> d = {k: v for k, v in map(lambda i: i.split('='), s.split())}
>>> {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}

How to split values in a nested dictionary by characters

Lets say I have a nested dictionary
nested_dict={"dict1":{"key1":"value1", "key2":"value2", "key3":"value3;value4"}}
Now I want to split value3 and value 4 under the same key like this,
nested_dict={"dict1":{"key1":"value1", "key2":"value2", 'key3': ['value3', 'value4']}}
What would be the best way to do so in Python?
use the fact that dict is mutable and you can recursively change anything under the sun :P
nested_dict={"dict1":{"key1":"value1", "key2":"value2", "key3":"value3;value4"}}
def sol(d):
for i in d:
if type(d[i]) is dict:
sol(d[i])
else:
d[i] = d[i].split(';')
if len(d[i])==1: d[i] = d[i][0]
sol(nested_dict)
print(nested_dict)
{'dict1': {'key1': 'value1', 'key2': 'value2', 'key3': ['value3', 'value4']}}

list of dictionaries from single dictionary

I have a dictionary like this
dict1 = {'key1': 'value1', 'key2': 'value2'}
how do I have an array of the keys and values as dictionaries like this
array_of_dict_values = [{'key1': 'value1'}, {'key2': 'value2'}]
What would be the easiest way to accomplish this?
You can do this:
>>> aDict = {'key1': 'value1', 'key2': 'value2'}
>>> aList = [{k:v} for k, v in aDict.items()]
>>> aList
[{'key2': 'value2'}, {'key1': 'value1'}]
While somebody already answered with how to do this, I'm going to answer with "you probably don't want to do this." If every entry is a dictionary with a single key, wouldn't a list of key-value pairs work just as well?
dictionary = {'key1': 'value1', 'key2': 'value2'}
print(list(dictionary.items()))
# [('key2', 'value2'), ('key1', 'value1')]

Python: list of dictionaries, how to get values of a specific key for multiple items of the list?

I have a list of dictionaries like:
dict_list = [{'key1': 'dict1_value1', 'key2': 'dict1_value2', 'key3': 'dict1_value3'},
{'key1': 'dict2_value1', 'key2': 'dict2_value2', 'key3': 'dict2_value3'},
{'key1': 'dict3_value1', 'key2': 'dict3_value2', 'key3': 'dict3_value3'},
{'key1': 'dict4_value1', 'key2': 'dict4_value2', 'key3': 'dict4_value3'},
{'key1': 'dict5_value1', 'key2': 'dict5_value2', 'key3': 'dict5_value3'}]
getting the value for 'key3' for the second list item is like:
dict_list[1]['key3']
dict2_value3
and also the code below returns items 2:4 from the list:
dict_list[1:3]
What if I want to get values for 'key3' for multiple items from the list. like
dict_list[1:3]['key3']
something similar to what we do in MATLAB.
>>> [x.get('key3') for x in dict_list[1:3]]
['dict2_value3', 'dict3_value3']
[dict_list[i]['key3'] for i in xrange(1,3)]
OR
[operator.itemgetter('key3')(dict_list[i]) for i in range(1,3)]
OR
map(operator.itemgetter('key3'), itertools.islice(dict_list, 1,3))
[x['key3'] for x in dict_list[1:3]]

single list to dictionary

I have this list:
single = ['key1', 'value1', 'key2', 'value2', 'key3', 'value3']
What's the best way to create a dictionary from this?
Thanks.
>>> single = ['key1', 'value1', 'key2', 'value2', 'key3', 'value3']
>>> dict(zip(single[::2], single[1::2]))
{'key3': 'value3', 'key2': 'value2', 'key1': 'value1'}
Similar to SilentGhost's solution, without building temporary lists:
>>> from itertools import izip
>>> single = ['key1', 'value1', 'key2', 'value2', 'key3', 'value3']
>>> si = iter(single)
>>> dict(izip(si, si))
{'key3': 'value3', 'key2': 'value2', 'key1': 'value1'}
This is the simplest I guess. You will see more wizardry in solution here using list comprehension etc
dictObj = {}
for x in range(0, len(single), 2):
dictObj[single[x]] = single[x+1]
Output:
>>> single = ['key1', 'value1', 'key2', 'value2', 'key3', 'value3']
>>> dictObj = {}
>>> for x in range(0, len(single), 2):
... dictObj[single[x]] = single[x+1]
...
>>>
>>> dictObj
{'key3': 'value3', 'key2': 'value2', 'key1': 'value1'}
>>>
L = ['key1', 'value1', 'key2', 'value2', 'key3', 'value3']
d = dict(L[n:n+2] for n in xrange(0, len(L), 2))
>>> single = ['key', 'value', 'key2', 'value2', 'key3', 'value3']
>>> dict(zip(*[iter(single)]*2))
{'key3': 'value3', 'key2': 'value2', 'key': 'value'}
Probably not the most readable version though ;)
You haven't specified any criteria for "best". If you want understandability, simplicity, easily modified to check for duplicates and odd number of inputs, works with any iterable (in case you can't find out the length in advance), NO EXTRA MEMORY USED, ... try this:
def load_dict(iterable):
d = {}
pair = False
for item in iterable:
if pair:
# insert duplicate check here
d[key] = item
else:
key = item
pair = not pair
if pair:
grumble_about_odd_length(key)
return d

Categories