Home > Enterprise >  dictionery with duplicates keys
dictionery with duplicates keys

Time:08-19

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 reprs 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'}
  • Related