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'>.

Asked By: Memories

||

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.

Answered By: wim
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.