Ryan
Ryan

Reputation: 416

Python dictionary key error only in one specific case

I have a class that stores a list of lists in a matrix style, and it can just be indexed like [x,y].

Right now I have these set:

test_dict = {1:"cow",2:"horse"}

randommap = mapArray(None, (20,20))

random map is just filled with lists of 1s. So any index will return a 1. But here is where I get lost, maybe because of a misunderstanding about how dictionaries work:

test_dict[1]

That obviously gives back "cow" and

randommap[1,1] #or any two x,y values up to 20 for that matter

gives me a value of 1.

But how come this gives me a key error:

test_dict[randommap[1,1]]

In isolation, indexing randommap there gives me a value of 1, so shouldn't that 1 be supplied as an index for test_dict, thus returning me "cow"?

Update: These are the two methods I presume are causing the issue. It appears that they are returning strings instead of integers, but I don't know If I quite understand the difference between the two.

def __str__(self):
    return str(self.mapdata)

def __repr__(self):
    return str(self.mapdata)

Here is the overloaded __getitem__ method:

def __getitem__(self, (x,y)):
    #Just reverses it so it works intuitively and the array is 
    # indexed simply like map[x,y] instead of map[y][x]
    return mapArray(self.mapdata[y][x])

Sorry the formatting seems to have been messed up a bit.

Upvotes: 1

Views: 290

Answers (2)

Martijn Pieters
Martijn Pieters

Reputation: 1123820

There is a difference between 1 (and integer), "1" (a string), and any custom class whose __repr__() method returns the string "1" when called. They will all be printed as 1 in the console, but are not equivalent for dict look-ups.

You need to check that type(randommap[1, 1]) is indeed an int.

Update: Your __getitem__ method doesn't return integers, it returns a new instance of your mapArray class. Did you mean to return just the values themselves? E.g.:

def __getitem__(self, (x,y)):
    #Just reverses it so it works intuitively and the array is 
    # indexed simply like map[x,y] instead of map[y][x]
    return self.mapdata[y][x]

Upvotes: 1

jmetz
jmetz

Reputation: 12783

Given the updated question, it seems that __getitem__ returns a new mapArray.

I think your overloaded __getitem__ should be something like

def __getitem__(self, (x,y)):
    return self.mapdata[y][x] 

instead, (assuming that the [y][x] order is intentional).

Upvotes: 0

Related Questions