I am trying to append duplicated keys in a dictionary. I Have seen a solution in http://www.wellho.net/mouth/3934_Multiple-identical-keys-in-a-Python-dict-yes-you-can-.html.
class person(object):
def __init__(self,name):
self.name = name
alternate = {person("Andrew") : "Cambridge", person("Barabara") : "Bloomsbury", person("Andrew"): "Corsica"}
print(alternate)
what am I getting a result like
{<__main__.person at 0x17b020c46a0>: 'Cambridge',
<__main__.person at 0x17b020c43a0>: 'Bloomsbury',
<__main__.person at 0x17b018fda90>: 'Corsica'}
but what I want
{'Barabara': 'Bloomsbury', 'Andrew': 'Cambridge', 'Andrew': 'Corsica'}
please help me
CodePudding user response:
I'm not sure how this is going to work in practice (e.g., how are you gonna get the Andrew you want?)
But to answer your question in the most strictly fashion, your Person
class needs a __repr__
method defined for how to represent itself.
class person(object):
def __init__(self,name):
self.name = name
def __repr__(self):
return self.name
alternate = {person("Andrew") : "Cambridge", person("Barabara") : "Bloomsbury", person("Andrew"): "Corsica"}
print(alternate)
# output
{Andrew: 'Cambridge', Barabara: 'Bloomsbury', Andrew: 'Corsica'}
CodePudding user response:
This is the normal python behaviour. The keys of your dict are object, which, by default, are represented by <__main__.person at 0x17b020c46a0>
. Here, __main__.person
is the class name, and 0x17b020c46a0
is the adress of your object.
You can create your own object representation so that it displays the name:
class person(object):
def __init__(self,name):
self.name = name
def __repr__(self):
return self.name
alternate = {person("Andrew") : "Cambridge", person("Barabara") : "Bloomsbury", person("Andrew"): "Corsica"}
print(alternate)
It returns {Andrew: 'Cambridge', Barabara: 'Bloomsbury', Andrew: 'Corsica'}
as intended.
CodePudding user response:
You need to define __repr__
inside your class:
class person(object):
def __init__(self,name):
self.name = name
def __repr__(self):
return repr(self.name)
alternate = {person("Andrew"): "Cambridge", person("Barabara"): "Bloomsbury", person("Andrew"): "Corsica"}
print(alternate)
Output: {'Andrew': 'Cambridge', 'Barabara': 'Bloomsbury', 'Andrew': 'Corsica'}
When a dict is printed it uses the repr
s of the keys and values. This is basically what the dict.__str__
method looks like:
def __str__(self):
ret = '{'
for i, (k, v) in enumerate(self.items()):
ret = f'{repr(k)}: {repr(v)}' # See how it uses repr here
if i != len(self) - 1:
ret = ', '
return ret '}'
But, this really isn't going to work in practice. As you can see below, you can't get the actual value back:
>>> alternate['Andrew']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'Andrew'
>>> alternate[person('Andrew')]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'Andrew'
>>> list(alternate.values())[list(alternate.keys()).index(person('Andrew'))]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Andrew is not in list
CodePudding user response:
When you are printing to console, the object will be represented by it's __repr__
, and as such you need to definite it appropriately to get the desired representation for your object. So if we make it so our representation of this person
class is simply self.name
as such:
class person(object):
def __init__(self,name):
self.name = name
def __repr__(self):
return self.name
Then we will get the desired result:
>>> alternate = {person("Andrew") : "Cambridge", person("Barabara") : "Bloomsbury", person("Andrew"): "Corsica"}
>>> print(alternate)
>>> {Andrew: 'Cambridge', Barabara: 'Bloomsbury', Andrew: 'Corsica'}