Reputation: 1071
I'm having some issues filling a list in Python. I keep getting a list index out of range error. The output of len(network) is 7 so I figured filling it from 0-6 should work to give me a 7x7 list.
def fillNodeTable():
nodeTable = []
for x in xrange(0, (len(network) -1)):
for y in xrange(0, (len(network) -1)):
nodeTable[x][y].append(Node)
print nodeTable
So I ended up with this and it works
n = len(network)
nodeTable = [[Node]*n for x in xrange(n)]
When I print the nodeTable to debug I get the following:
<class __main__.Node at 0xb737914c>
Is this just because I'm appending a class to each entry or have I done something else wrong here?
Upvotes: 1
Views: 4650
Reputation: 35089
If we go through your code a step at a time, the problem becomes clearer:
nodeTable = []
So, nodeTable
is an empty list.
We start a loop, and immediately start another one - so take the first iteration, where x
and y
are both 0.
nodeTable[x][y].append(Node)
So this says: find the 0th item in nodeTable
, find the 0th item in that, and call append
on it. This will error, because nodeTable
is empty - it has no 0th item to find. So, the solution is to give it one before we reach this point. This will work:
for x in xrange(0, (len(network) -1)):
nodeTable.append([])
for y in xrange(0, (len(network) -1)):):
nodeTable[x].append(Node)
However, there's still a couple of things to note: first, this will give you (len(network) - 1) * (len(network) -1)
copies of Node
, arranged in nested lists. If Node
is a class like its name suggests, that means you'll get that many copies of that class, not that many individual instances of that class. For that, you would: .append(Node)
.
The next thing is that, as others have mentioned, this can be written as a nested list comprehension:
[[Node() for y in xrange(0, (len(network -1))] for x in xrange(0, (len(network) -1))]
For exactly the same effect, though probably a bit more efficient.
Third, xrange
will assume the 0 if you don't give it explicitly - ie,
xrange(len(network) - 1)
Is equivalent to your:
xrange(0, (len(network) - 1))
Finally, xrange(len(network) - 1)
probably isn't what you want anyway. This will make nodeTable
and each list inside it one element shorter than network
. xrange
stops before the stop
value, not at it. This means you probably want [for x in xrange(len(network))]
. But doing it as a list comprehension, we no longer use x
or y
, which means we don't need them to take numbers in particular:
[[Node() for x in network] for y in network]
, as suggested by @jcollado , will do the same thing.
Upvotes: 1
Reputation: 195
The way you have defined the list is the problem. You have defined you list as single dimensional list and try to use it as multi dimensional list. Try the below solution.
Code:
def fillNodeTable():
nodeTable = [[[] for i in range(7)] for i in range(7)]
for x in xrange(0, (len(network))):
for y in xrange(0, (len(network))):
nodeTable[x][y].append("Node")
for x in xrange(0, (len(network))):
print
for y in xrange(0, (len(network))):
print nodeTable[x][y],
Output:
['Node'] ['Node'] ['Node'] ['Node'] ['Node'] ['Node'] ['Node']
['Node'] ['Node'] ['Node'] ['Node'] ['Node'] ['Node'] ['Node']
['Node'] ['Node'] ['Node'] ['Node'] ['Node'] ['Node'] ['Node']
['Node'] ['Node'] ['Node'] ['Node'] ['Node'] ['Node'] ['Node']
['Node'] ['Node'] ['Node'] ['Node'] ['Node'] ['Node'] ['Node']
['Node'] ['Node'] ['Node'] ['Node'] ['Node'] ['Node'] ['Node']
['Node'] ['Node'] ['Node'] ['Node'] ['Node'] ['Node'] ['Node']
Upvotes: 0
Reputation: 39628
The problem is that xrange(0, 6)
will give you 6 items, from 0 to 5.
>>> len(xrange(0,6))
6
>>> len(xrange(0,7))
7
Upvotes: 3
Reputation: 40424
I think you can use a list comprehension since it would be clearer:
nodeTable = [[Node for x in network] for y in network]
Upvotes: 4
Reputation: 7041
I think you are porting a MATLAB code. You are getting the out of range error on nodeTable. You initialize it to an empty array.
Try something like this, or use the array classes in numpy:
> a = []
>>> for i in xrange(3):
... a.append([])
... for j in xrange(3):
... a[i].append(i+j)
or
n = 7
a = [[0]*n for x in xrange(n)]
Upvotes: 2