Reputation: 187
I am trying to make a 2d subclass of the list
object called map2d. I want to be able to initialize map2d
and get a 2d array of a defined size.
E.g,
class map2d(list):
def __init__(self,x,y):
# Magic code that makes this work
Map = map2d(3,2)
print(Map)
Output
[[None, None], [None,None], [None,None]]
What I Tried
class map2d(list):
def __init__(self,x,y):
self = [[None for _ in range(y)] for _ in range(x)]
I know that this is probably a perversion of everything sacred but it makes sense to me.
Thanks in advance,
John
Upvotes: 0
Views: 66
Reputation: 95948
There is nothing magical about self
. When you assign anything to self
, e.g. self = whatever
that works how assignment always works in Python: now self
refers to whatever object whatever
referred to. Assignment never mutates. You need to use mutator methods, like .append
or .extend
or index/slice based assignment. Here's a simple way:
In [1]: class map2d(list):
...: def __init__(self,x,y):
...: for _ in range(x):
...: r = []
...: self.append(r)
...: for _ in range(y):
...: r.append(None)
...:
In [2]: map2d(2,3)
Out[2]: [[None, None, None], [None, None, None]]
However, I see no good reason to use inheritance for this. Just create a helper function:
In [3]: def map2d(x,y):
...: return [[None for _ in range(y)] for _ in range(x)]
...:
In [4]: map2d(2,3)
Out[4]: [[None, None, None], [None, None, None]]
Note a list is not an array, and lists don't have "dimensions", they only have a length.
If you really want to prevent negative indexing, you could do:
In [10]: class MyList(list):
...: def __getitem__(self, item):
...: if isinstance(item, int) and item < 0:
...: raise TypeError("MyList indices must be positive")
...: self.__getitem__(item)
...:
In [11]: x = MyList()
In [12]: x.append(3)
In [13]: x[-1]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-13-c30dd0d358dc> in <module>()
----> 1 x[-1]
<ipython-input-10-f2169a236374> in __getitem__(self, item)
2 def __getitem__(self, item):
3 if isinstance(item, int) and item < 0:
----> 4 raise TypeError("MyList indices must be positive")
5 self.__getitem(item)
6
TypeError: MyList indices must be positive
Upvotes: 1
Reputation: 1808
If you are just creating a list within a list, there is no need to use classes:
def map2d(x, y):
return [[None for _ in range(y)] for _ in range(x)]
print(map2d(3, 2)) # [[None, None], [None,None], [None,None]]
This will give you the desired output.
Also, note that if you are looking to customize the way a class is printed, you should use the method __str__
, eg:
class Example:
def __str__(self):
return "Example Class Object"
print(Example()) # Example Class Object
Upvotes: 1