Is it reasonable to use None as a dictionary key in Python?
None seems to work as a dictionary key, but I am wondering if that will just lead to trouble later. For example, this works:
>>> x={'a':1, 'b':2, None:3}
>>> x
{'a': 1, None: 3, 'b': 2}
>>> x[None]
3
The actual data I am working with is educational standards. Every standard is associated with a content area. Some standards are also associated with content subareas. I would like to make a nested dictionary of the form {contentArea:{contentSubArea:[standards]}}
. Some of those contentSubArea keys would be None.
In particular, I am wondering if this will lead to confusion if I look for a key that does not exist at some point, or something unanticipated like that.
Solution 1:
Any hashable value is a valid Python Dictionary Key. For this reason, None is a perfectly valid candidate. There's no confusion when looking for non-existent keys - the presence of None as a key would not affect the ability to check for whether another key was present. Ex:
>>> d = {1: 'a', 2: 'b', None: 'c'}
>>> 1 in d
True
>>> 5 in d
False
>>> None in d
True
There's no conflict, and you can test for it just like normal. It shouldn't cause you a problem. The standard 1-to-1 Key-Value association still exists, so you can't have multiple things in the None key, but using None as a key shouldn't pose a problem by itself.
Solution 2:
You want trouble? here we go:
>>> json.loads(json.dumps({None:None}))
{u'null': None}
So yea, better stay away from json if you do use None
as a key. You can patch this by custom (de/)serializer, but I would advise against use of None
as a key in the first place.
Solution 3:
None
is not special in any particular way, it's just another python value. Its only distinction is that it happens to be the return value of a function that doesn't specify any other return value, and it also happens to be a common default value (the default arg of dict.get()
, for instance).
You won't cause any run-time conflicts using such a key, but you should ask yourself if that's really a meaningful value to use for a key. It's often more helpful, from the point of view of reading code and understanding what it does, to use a designated instance for special values. Something like:
NoSubContent = SubContentArea(name=None)
{"contentArea":
{NoSubContent:[standards],
SubContentArea(name="Fruits"): ['apples', 'bananas']}}
Solution 4:
jsonify does not support a dictionary with None key.
From Flask import jsonify
def json_():
d = {None: 'None'}
return jsonify(d)
This will throw an error:
TypeError: '<' not supported between instances of 'NoneType' and 'str'
Solution 5:
It seems to me, the larger, later problem is this. If your process is creating pairs and some pairs have a "None" key, then it will overwrite all the previous None pairs. Your dictionary will silently throw out values because you had duplicate None keys. No?