Reputation: 2830
I'm using a dictionary in python to make what is basically an infinite 2d array by using a tuple as the key
grid = {}
grid[(0,0)] = cell()
the value 'cell' is a new object. Can I have, say, a function within that object that is able to get its key value? ie. (0,0)
I could just put that data in the object itself but then I'd have it existing twice which seems like bad programming. Thanks!
Upvotes: 0
Views: 723
Reputation: 13495
Give your cell
class an address
attribute, which is a two-tuple, e.g. (0,0)
. Give the cell
class a __hash__
method, which returns hash(self.address)
.
class cell:
def __init__(self,address):
self.address = address
def __hash__(self):
return hash(self.address)
def __eq__(self):
return hash(self) == hash(other)
You can still access cells by their address, but the cells know where they belong.
>>> c = cell((0,0))
>>> c
<so.cell instance at 0xb74c6a2c>
>>> grid = dict()
>>> grid[c] = c
>>> grid[c]
<so.cell instance at 0xb74c6a2c>
>>> grid[(0,0)]
<so.cell instance at 0xb74c6a2c>
I'm not sure what else your cell
s need to know and/or do, but if you're just doing numerical stuff here, I'd highly recommend the scipy.sparse module.
Upvotes: 0
Reputation: 113988
class cell(object):
def my_idx(self,grid):
return grid.keys()[grid.values().index(self)]
then call it
some_cell.my_idx(grid)
Upvotes: 1
Reputation: 1532
There are two separate issues here... first, to access the grid from within cell, I would have cell
's constructor take a reference to grid as a mandatory argument.
grid = {}
grid[(0,0)] = cell(grid)
and
class cell:
def __init__(self, gridRef):
self.grid = gridRef
But, accessing the key is more challenging. One reason is that a dictionary is not a one-to-one mapping, so the same cell object may have multiple keys in your dictionary. You'd need to iterate over your keys and look for it, either manually or through flipping the dictionary. How about making your cell
constructor take the key as well?
grid = {}
grid[(0,0)] = cell(grid, (0,0))
If that's too redundant, then maybe something like this?
def addToGrid(myDict, myCell):
myDict[myCell.key()] = myCell
and then...
grid = {}
addToGrid(grid, cell(grid, (0, 0)))
where your cell
class takes the dictionary key as the second argument and returns it via the key()
method.
Upvotes: 1
Reputation: 15702
Your questions implies that there's a 1:1 mapping between dict keys and their values, which is not true. Take this code:
grid = {}
c = cell()
grid[(0,0)] = c
grid[(0,1)] = c
That's perfectly valid in python, even if your use case does not allow it. What index should the function you are looking for return for c
?
Storing the data twice does not have to be bad programming style, but your memory might be limited. If your cell
needs to know it's index, it must have that data. If you see your cells as a list of items, the dict becomes just a index for faster access. And having indexes for faster access is of course no bad programming style. ;-)
Upvotes: 1
Reputation: 10585
This should work:
class Cell(object):
def get_idx(self, grid):
"""
>>> cell = Cell()
>>> cell.get_idx({(0, 0): cell})
(0, 0)
>>> cell = Cell()
>>> cell.get_idx({(0, 0): Cell(), (1, 1): cell, (2, 2): Cell()})
(1, 1)
"""
return [x[0] for x in grid.items() if x[1] == self][0]
Just notice that it won't give you realiable results if the object is more than once in the dict and it would raise an exception if the object isn't in the dict.
Also it could be slow on very large grids.
Upvotes: 1