1

I need a dictionary that has two keys with the same name, but different values. One way I tried to do this is by creating a class where I would put the each key name of my dictionary, so that they would be different objects:

names = ["1", "1"]
values = [[1, 2, 3], [4, 5, 6]]
dict = {}

class Sets(object):
    def __init__(self,name):
        self.name = name

for i in range(len(names)):
    dict[Sets(names[i])] = values[i]

print dict

The result I was expecting was:

{"1": [1, 2, 3], "1": [4, 5, 6]}

But instead it was:

{"1": [4, 5, 6]}

[EDIT] So I discovered that keys in a dictionary are meant to be unique, having two keys with the same name is a incorrect use of dictionary. So I need to rethink my problem and use other methods avaliable in Python.

arthurckl
  • 5,281
  • 6
  • 17
  • 16
  • 2
    You would be using a wrong tool for a problem. Dictionary key are useful for uniqueness. :|. Better explain what exactly is your input and output requirement with a real example. – Nagaraj Tantri Jun 04 '15 at 16:07
  • "I need a dictionary that has two keys with the same name, but different values." Why do you think you need this? I suggest you either map the unique keys to lists of values (lists of lists in your case) or just use a list of tuples (key, value) – tobias_k Jun 04 '15 at 16:07
  • 4
    Dictionaries always have **unique** keys. You cannot do what you want to do with a dictionary. Perhaps you are trying to solve the wrong problem, why do you think you need this? – Martijn Pieters Jun 04 '15 at 16:08
  • 1
    Why do you *need* it? how are you going to use it? what do you expect to be the value of `dict["1"]`? If you explain the context, we can suggest a good approach. (also, don't name your variable `dict`) – shx2 Jun 04 '15 at 16:08
  • Also, your workaround works fine. – Vincent Jun 04 '15 at 16:09
  • @Vincent The workaround does not work. How would you retrieve a value this way? Either you create a new `Sets`, but this will have a different hash (the reason it seems to work in the first place), or you iterate all the keys and compare the `name`, but then you can just as well use a list of tuples. – tobias_k Jun 04 '15 at 16:14
  • Why don't use just used a paired tuple instead, for example: `[(1, 'valueA'), (2, 'valueB')]` – Malik Brahimi Jun 04 '15 at 16:15
  • Ok people, sorry for my misunderstood. Initially I had different key names for different pictures of me "arthur.jpg". I extracted the pixels values for each picture, then I arranged them in my dictionary where the key would be the picture name in alphabetical and numerical order(ex:"arthur1.jpg","arthur2.jpg"...) and its values are the pixels values for each of them. I am trying to make a dataset for my face recognition, but for that the keys names for different "arthur.jpg" need all to be labeled into a single variable or name (in this case, "1"). – arthurckl Jun 04 '15 at 16:31
  • Also you definitely did not search before you posted because this same question has come up like 3 times in the last 2 days. – Two-Bit Alchemist Jun 04 '15 at 18:13

2 Answers2

5

What you are trying to do is not possible with dictionaries. In fact, it is contrary to the whole idea behind dictionaries.

Also, your Sets class won't help you, as it effectively gives each name a new (sort of random) hash code, making it difficult to retrieve items from the dictionary, other than checking all the items, which defeats the purpose of the dict. You can not do dict.get(Sets(some_name)), as this will create a new Sets object, having a different hash code than the one already in the dictionary!

What you can do instead is:

  1. Just create a list of (name, value) pairs, or

    pairs = zip(names, values) # or list(zip(...)) in Python 3
    
  2. create a dictionary mapping names to lists of values.

    dictionary = {}
    for n, v in zip(names, values):
        dictionary.setdefault(n, []).append(v)
    

The first approach, using lists of tuples, will have linear lookup time (you basically have to check all the entries), but the second one, a dict mapping to lists, is as close as you can get to "multi-key-dicts" and should serve your purposes well. To access the values per key, do this:

for key, values in dictionary.iteritems():
    for value in values:
        print key, value
tobias_k
  • 81,265
  • 12
  • 120
  • 179
2

Instead of wanting multiple keys with the same name, could you getting away of having multiple values per each key?

names = [1]
values = [[1, 2, 3], [4, 5, 6]]

dict = {}

for i in names:
    dict[i] = values

for k,v in dict.items():
    for v in dict[k]:
        print("key: {} :: v: {}".format(k, v))

Output:

key: 1 :: v: [1, 2, 3]
key: 1 :: v: [4, 5, 6]

Then you would access each value like this (or in a loop):

print("Key 1 value 1: {}".format(dict[1][0]))
print("Key 1 value 2: {}".format(dict[1][1]))
stevieb
  • 9,065
  • 3
  • 26
  • 36