Reputation: 194
Consider following dictionary:
dict1 = {"A":{"B":"C"}}
print(dict1["A"]["B"])
This prints 'C'
I can now modify my dictionary like this
dict1["A"]["B"] = "D"
dict1["A"]["E"] = "F"
dict1["B"] = "G"
print(dict1)
And the output is
{'A': {'B': 'D', 'E': 'F'}, 'B': 'G'}
but I can't do this:
dict1["C"]["H"] = ["I"]
this however works:
dict2 = {"H":"I"}
dict1["C"] = dict2
print(dict1)
Output:
{'A': {'B': 'D', 'E': 'F'}, 'B': 'G', 'C': {'H': 'I'}}
Is there an alternative that doesn't require creating an additional dictionary?
I am just playing around to learn the language and not working on a concrete project. Still, any help would be appreciated
Upvotes: 3
Views: 76
Reputation: 10173
There's a one-liner tree in https://gist.github.com/hrldcpr/2012250. It was posted as a cute hack, but works reasonably well.
from collections import defaultdict
def tree(): return defaultdict(tree)
users = tree()
users['harold']['username'] = 'hrldcpr'
users['handler']['username'] = 'matthandlersux'
Because of the defaultdict
, each access on an undefined key generates a new value, and because of the recursion the new value will also be a new tree.
Upvotes: 0
Reputation: 10647
You haven't created the dictionary C
yet. In python you must first create it before editing it. Like this:
dict1 = {}
dict1["C"] = {} # First create it before modifying it
dict1["C"]["H"] = ["I"]
print(dict1)
Let me explain.
foomain["C"] = 'blah'
sets it, but
foomain['C']['H'] = 'blah'
attempts to find foomain['C']
, and fails. If it worked, it would then take that dictionary and use the assignment operator on it to assign blah
to ['C']['H']
.
It's like saying:
Okay, go find `foomain['C']`, then assign 'blah' to key 'H'
Instead of:
Okay, assign 'blah' to `foomain['C']['H']`
In other words, assignment and getting are entirely different in python.
Upvotes: 2
Reputation:
dict1["C"]["H"] = ["I"]
In the above, the problem is that dict1["C"]
has not been initialized, and so it is not known whether it is a dict and can be assigned a sub-element like ["H"]
(or whether it is just, say, an integer and assigning to ["H"]
would be an error).
There are packages to enable what you're talking about, and using a defaultdict would work for a single level of nestedness. But especially if you are starting out, it's probably better that you deal with such things explicitly.
val = dict1.get("C")
if isinstance(val, dict)
dict1["C"]["H"] = "I"
else
dict["C"] = {"H": "I"}
Upvotes: 1
Reputation: 16733
You can use setdefault which would assign default value in case of key error.
dict1.setdefault('C', {})['H'] = 'I'
Or you can altogether use defaultdict instead of dict.
from collections import defaultdict
Upvotes: 0
Reputation: 34527
Why would dict1["C"]["H"] = ["I"] work if there is no element "C" in dict1? Do this:
dict1["C"] = {}
dict1["C"]["H"] = ["I"]
Upvotes: 3