Strange python dictionary keys
Question:
I encounter a strange dictionary. Let’s call it cp_dict
. When I type:
cp_dict['ZnS-Zn']
it returns:
{Element Zn: -1.159460605, Element S: -4.384479766249999}
The child key looks like a string but without quotation marks. How I can access the child keys (for example: Element Zn
) and modify the values? I tried cp_dict['Zn3P2-Zn'][Element Zn]
, and the error is
SyntaxError: invalid syntax. Perhaps you forgot a comma?
The cp_dict['Zn3P2-Zn']['Element Zn']
leads to:
KeyError: 'Element Zn'
I checked type(cp_dict['ZnS-Zn'])
. It returns <class 'dict'>
.
Answers:
It is quite easy to make a custom class which represents itself in that way ("looking like a string but without quotation marks"). The result returned by a __repr__
method is what gets used when representing instances inside collections such as dicts and lists:
>>> class Element:
... def __init__(self, symbol):
... self.symbol = symbol
... def __repr__(self):
... return f"Element {self.symbol}"
...
>>> d = {Element("Zn"): -1.159460605, Element("S"): -4.384479766249999}
>>> d
{Element Zn: -1.159460605, Element S: -4.384479766249999}
So, my guess is the keys of the dict are the strange items, not the dict itself. Check the type of a key, and look up it’s __repr__
method. You can get the type of the first key with:
k = next(iter(cp_dict["ZnS-Zn"]))
Element = type(k)
To index the dict you will need an instance which compares equal with one of those keys. Again, look up type(k).__eq__
for that. If the __eq__
method is not customized, then you will need to use the identical key to index this dict, since the equality method will just be the default identity-based implementation which is inherited from object
.
I encounter a strange dictionary. Let’s call it cp_dict
. When I type:
cp_dict['ZnS-Zn']
it returns:
{Element Zn: -1.159460605, Element S: -4.384479766249999}
The child key looks like a string but without quotation marks. How I can access the child keys (for example: Element Zn
) and modify the values? I tried cp_dict['Zn3P2-Zn'][Element Zn]
, and the error is
SyntaxError: invalid syntax. Perhaps you forgot a comma?
The cp_dict['Zn3P2-Zn']['Element Zn']
leads to:
KeyError: 'Element Zn'
I checked type(cp_dict['ZnS-Zn'])
. It returns <class 'dict'>
.
It is quite easy to make a custom class which represents itself in that way ("looking like a string but without quotation marks"). The result returned by a __repr__
method is what gets used when representing instances inside collections such as dicts and lists:
>>> class Element:
... def __init__(self, symbol):
... self.symbol = symbol
... def __repr__(self):
... return f"Element {self.symbol}"
...
>>> d = {Element("Zn"): -1.159460605, Element("S"): -4.384479766249999}
>>> d
{Element Zn: -1.159460605, Element S: -4.384479766249999}
So, my guess is the keys of the dict are the strange items, not the dict itself. Check the type of a key, and look up it’s __repr__
method. You can get the type of the first key with:
k = next(iter(cp_dict["ZnS-Zn"]))
Element = type(k)
To index the dict you will need an instance which compares equal with one of those keys. Again, look up type(k).__eq__
for that. If the __eq__
method is not customized, then you will need to use the identical key to index this dict, since the equality method will just be the default identity-based implementation which is inherited from object
.