1

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?

asked Feb 14, 2012 at 9:45
4
  • 3
    I don't think this is your actual code, because there is a parenthesis missing in line 3. Commented Feb 14, 2012 at 9:48
  • I changed it from xrange(0, 6) when I was putting it up as I realised that would allow it to function if the size of 'network' changed as this is what its size is based on. Commented Feb 14, 2012 at 9:50
  • No need to subtract 1 as mentinoned below stackoverflow.com/a/9274833/72436 Commented Feb 14, 2012 at 10:00
  • Are you trying to fill the table with instances of class Node? Use Node() to create an instance. Commented Feb 14, 2012 at 11:04

5 Answers 5

4

I think you can use a list comprehension since it would be clearer:

nodeTable = [[Node for x in network] for y in network]
answered Feb 14, 2012 at 9:53

Comments

3

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
answered Feb 14, 2012 at 9:53

Comments

2

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)]
answered Feb 14, 2012 at 9:50

2 Comments

Note that [anything]*n behaves differently if anything is not a primitive type. It will create a list of n references to the same object.
@BjörnPollex that's not so much non-primitive types as mutable types.
1

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.

answered Feb 14, 2012 at 11:52

Comments

0

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']

answered Feb 14, 2012 at 10:17

1 Comment

This will fail the same way as the OP, for the same reason, if len(network) > 7.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.