patternpythonMinor
Updating a dict with dict values
Viewed 0 times
dictupdatingvalueswith
Problem
This code works and does exactly what I want it to, but I feel that it is inelegant. It seems like there should be a way to use get() and/or setdefault(), for example. All comments and suggestions are appreciated!
Here is a function that builds a dict. The dict's values are also dicts. Some of the values are empty dicts {} and some are dicts that have a {key:value} pair.
Typical (and desired) output:
```
{'test2': {}, 'test3': {'a_key': 'a_value'}, 'test0': {}, 'test1': {}, 'test4': {'hello': None}}
{'test2': {}, 'test3': {'a_key': 'a_value'}, 'test0': {'hello': None}, 'test1': {}}
{'test2': {}, 'test3': {'a_key': 'a_value'}, 'test0': {}, 'test1': {}}
{'test2': {}, 'test3': {'a_key': 'a_value'}, 'test0': {'NULL': None}, 'test1': {}}
{'test2': {}, 't
Here is a function that builds a dict. The dict's values are also dicts. Some of the values are empty dicts {} and some are dicts that have a {key:value} pair.
def my_function(my_string, my_key):
d = {}
for i in range(3):
d['test' + str(i)] = {}
d['test3'] = {'a_key': 'a_value'}
# d = { 'test0': {}, 'test1': {}, 'test2': {}, 'test3': {'a_key': 'a_value'} }
if my_string != '':
d[my_key] = {my_string: None}
else:
# check if d[my_key] exists
try:
# d[my_key] exists and it is not empty, don't overwrite
if d[my_key]:
pass
# d[my_key] exists, but it is empty, write NULL
else:
my_string = 'NULL'
d[my_key] = {my_string: None}
# d[my_key] did not exist, create it and write NULL
except KeyError:
my_string = 'NULL'
d[my_key] = {my_string: None}
return d
# my_string not blank, my_key is new
f = my_function('hello', 'test4')
print(f)
# my_string not blank, my_key exists
f = my_function('hello', 'test0')
print(f)
# my_string blank, my_key exists and its value is not empty
f = my_function('', 'test3')
print(f)
# my_string blank, my_key exists and its value is empty
f = my_function('', 'test0')
print(f)
# my_string blank, my_key is new
f = my_function('', 'test4')
print(f)Typical (and desired) output:
```
{'test2': {}, 'test3': {'a_key': 'a_value'}, 'test0': {}, 'test1': {}, 'test4': {'hello': None}}
{'test2': {}, 'test3': {'a_key': 'a_value'}, 'test0': {'hello': None}, 'test1': {}}
{'test2': {}, 'test3': {'a_key': 'a_value'}, 'test0': {}, 'test1': {}}
{'test2': {}, 'test3': {'a_key': 'a_value'}, 'test0': {'NULL': None}, 'test1': {}}
{'test2': {}, 't
Solution
Tests
It's a good thing you've provided tests and expected output so that one can check the behavior, it is even better if one can run the tests without having to check that the output is correct. Only a tiny bit of reorganisation is required to get :
Improvements
Also, you could use
Thus, the code becomes :
Also, your dict initialisation could be done with a dictionnary comprehension. Then, your whole function would become:
Is this as simple as it can be ? Not quite ? The check for
It's a good thing you've provided tests and expected output so that one can check the behavior, it is even better if one can run the tests without having to check that the output is correct. Only a tiny bit of reorganisation is required to get :
# my_string not blank, my_key is new
assert my_function('hello', 'test4') == {'test2': {}, 'test3': {'a_key': 'a_value'}, 'test0': {}, 'test1': {}, 'test4': {'hello': None}}
# my_string not blank, my_key exists
assert my_function('hello', 'test0') == {'test2': {}, 'test3': {'a_key': 'a_value'}, 'test0': {'hello': None}, 'test1': {}}
# my_string blank, my_key exists and its value is not empty
assert my_function('', 'test3') == {'test2': {}, 'test3': {'a_key': 'a_value'}, 'test0': {}, 'test1': {}}
# my_string blank, my_key exists and its value is empty
assert my_function('', 'test0') == {'test2': {}, 'test3': {'a_key': 'a_value'}, 'test0': {'NULL': None}, 'test1': {}}
# my_string blank, my_key is new
assert my_function('', 'test4') == {'test2': {}, 'test3': {'a_key': 'a_value'}, 'test0': {}, 'test1': {}, 'test4': {'NULL': None}}
# New test from Sjoerd Job Postmus's comment
assert my_function('something not empty', 'test3') == {'test1': {}, 'test0': {}, 'test3': {'something not empty': None}, 'test2': {}}Improvements
if my_string != '': could be rewritten more concisely : if my_string:.Also, you could use
get to retrievement elements in a "safe" way.Thus, the code becomes :
if my_string:
d[my_key] = {my_string: None}
else:
if not d.get(my_key):
d[my_key] = {'NULL': None}
return dAlso, your dict initialisation could be done with a dictionnary comprehension. Then, your whole function would become:
def my_function(my_string, my_key):
d = {'test' + str(i): {} for i in range(3)}
d['test3'] = {'a_key': 'a_value'}
if my_string:
d[my_key] = {my_string: None}
elif not d.get(my_key):
d[my_key] = {'NULL': None}
return dIs this as simple as it can be ? Not quite ? The check for
d.get(my_key) is actually to distinguish "test3" from the other values. It could be easier to just do the obvious thing instead of trying to retrieve stuff from the dict :def my_function(my_string, my_key):
d = {'test' + str(i): {} for i in range(3)}
d['test3'] = {'a_key': 'a_value'}
if my_string:
d[my_key] = {my_string: None}
elif my_key != 'test3':
d[my_key] = {'NULL': None}
return dCode Snippets
# my_string not blank, my_key is new
assert my_function('hello', 'test4') == {'test2': {}, 'test3': {'a_key': 'a_value'}, 'test0': {}, 'test1': {}, 'test4': {'hello': None}}
# my_string not blank, my_key exists
assert my_function('hello', 'test0') == {'test2': {}, 'test3': {'a_key': 'a_value'}, 'test0': {'hello': None}, 'test1': {}}
# my_string blank, my_key exists and its value is not empty
assert my_function('', 'test3') == {'test2': {}, 'test3': {'a_key': 'a_value'}, 'test0': {}, 'test1': {}}
# my_string blank, my_key exists and its value is empty
assert my_function('', 'test0') == {'test2': {}, 'test3': {'a_key': 'a_value'}, 'test0': {'NULL': None}, 'test1': {}}
# my_string blank, my_key is new
assert my_function('', 'test4') == {'test2': {}, 'test3': {'a_key': 'a_value'}, 'test0': {}, 'test1': {}, 'test4': {'NULL': None}}
# New test from Sjoerd Job Postmus's comment
assert my_function('something not empty', 'test3') == {'test1': {}, 'test0': {}, 'test3': {'something not empty': None}, 'test2': {}}if my_string:
d[my_key] = {my_string: None}
else:
if not d.get(my_key):
d[my_key] = {'NULL': None}
return ddef my_function(my_string, my_key):
d = {'test' + str(i): {} for i in range(3)}
d['test3'] = {'a_key': 'a_value'}
if my_string:
d[my_key] = {my_string: None}
elif not d.get(my_key):
d[my_key] = {'NULL': None}
return ddef my_function(my_string, my_key):
d = {'test' + str(i): {} for i in range(3)}
d['test3'] = {'a_key': 'a_value'}
if my_string:
d[my_key] = {my_string: None}
elif my_key != 'test3':
d[my_key] = {'NULL': None}
return dContext
StackExchange Code Review Q#117431, answer score: 4
Revisions (0)
No revisions yet.