Dylan.Rockefeller
Dylan.Rockefeller

Reputation: 87

Simple List Error Python

In the following code, I created a list of lists, like an array. I began getting a "list assignment out of range" error. As a workaround for this error, I added 2 extra instances of diceSumTable, is you can see in the code. It will print now, but it is preceded by "2, 3". In my studying, I can't recall any reason why this would be happening if every instance of diceSumTable is already defined.

EDIT: Here was the original code, without applying the workaround.

def dice():

    diceSumTable = [2,3,4,5,6,7,8,9,10,11,12]

    diceSumTable[2] = [(1,1)]
    diceSumTable[3] = [(1,2),(2,1)]
    diceSumTable[4] = [(1,3),(2,2),(3,1)]
    diceSumTable[5] = [(1,4),(2,3),(3,2),(4,1)]
    diceSumTable[6] = [(1,5),(2,4),(3,3),(4,2),(5,1)]
    diceSumTable[7] = [(1,6),(2,5),(3,4),(4,3),(5,2),(6,1)]
    diceSumTable[8] = [(2,6),(3,5),(4,4),(5,3),(6,2)]
    diceSumTable[9] = [(3,6),(4,5),(5,4),(6,3)]
    diceSumTable[10] = [(4,6),(5,5),(6,4)]
    diceSumTable[11] = [(5,6),(6,5)]
    diceSumTable[12] = [(6,6)]

    #for illustrative purposes
    for i in diceSumTable:
        print i

dice()

Upvotes: 1

Views: 280

Answers (7)

Luc DUZAN
Luc DUZAN

Reputation: 1319

I am not shure of what result do you except from this code, what i understood is that you want to code to print :

[(1, 1)]
[(1, 2), (2, 1)]
[(1, 3), (2, 2), (3, 1)]
[(1, 4), (2, 3), (3, 2), (4, 1)]
[(1, 5), (2, 4), (3, 3), (4, 2), (5, 1)]
[(1, 6), (2, 5), (3, 4), (4, 3), (5, 2), (6, 1)]
[(2, 6), (3, 5), (4, 4), (5, 3), (6, 2)]
[(3, 6), (4, 5), (5, 4), (6, 3)]
[(4, 6), (5, 5), (6, 4)]
[(5, 6), (6, 5)]
[(6, 6)]

In this case, i think the error you are making is believing that the following line :

diceSumTable = [2,3,4,5,6,7,8,9,10,11,12,13,14]

Give you a list where index start from 2 and finish at 14, which is wrong because in Python every list index start at 0, and there is no way you can change that. The line you give me, actually create a list where the first index is 0 and the last index is 12 (size of the list - 1). And you list is such that diceSumTable[0] is 2 diceSumTable[1] is 3, etc.

This lead you to two options, either accept that list start at index 0, and if you want to keep using the mapping you want (i guess there is a reason for that, you surely want to associate 2 with (1,1), 3 with (1,2), (2,1)) just use diceSumTable[theNumberOfYourMapping -2]. Or as say haavee, you can use dict for that. But in this case, when you will iterate over your dict, you won't have you value is the write order. If there is no gap between you're wanted index i will go with the map. I think it will be great if you could explain use a bit more what you want to do, why do you want 2 and not 0 to be associated to [(1,1)]. Do you want to do something else with this lis t than printing it. To sum up here is the code, i would have written, if i understood what you wanted to do :

def dice():
    diceSumTable = [[(1,1)],
                    [(1,2),(2,1)],
                    [(1,3),(2,2),(3,1)],
                    [(1,4),(2,3),(3,2),(4,1)],
                    [(1,5),(2,4),(3,3),(4,2),(5,1)],
                    [(1,6),(2,5),(3,4),(4,3),(5,2),(6,1)],
                    [(2,6),(3,5),(4,4),(5,3),(6,2)],
                    [(3,6),(4,5),(5,4),(6,3)],
                    [(4,6),(5,5),(6,4)],
                    [(5,6),(6,5)],
                    [(6,6)]]

    #this is like for value in diceSumTable but i will iterate to 0,1..10 in more
    for (i,value) in enumerate(diceSumTable):
        print str(i+2) + " is associated to " + str(value)

dice()

Moreover if you want to know more about Python list, i could read :

http://effbot.org/zone/python-list.htm

And for Python dictionary :

http://www.pythonforbeginners.com/dictionary/dictionary-manipulation-in-pythonc

Upvotes: 0

zhangxaochen
zhangxaochen

Reputation: 34007

You should index the list by it's indices, not the values:

In [123]: lst = [3, 4, 5]

In [124]: lst[0] == 3 #item "3" is at index 0
Out[124]: True

In [125]: lst[3] #out of range
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-125-48d1ca706e8c> in <module>()
----> 1 lst[3] #out of range

IndexError: list index out of range

In [126]: lst[1] = 10 #if I want to change "4" in the list to "10"

In [127]: lst
Out[127]: [3, 10, 5]

Upvotes: 0

Holloway
Holloway

Reputation: 7367

When you set diceSumTable[2] you are replacing the third value in the list (lists are zero indexed - first value is name[0]) not the value that currently holds 2.

So after the first call you have diceSumTable equal to [2,3,[(1,1)],5,6,...].

I think what you could do is, as mentioned elsewhere, use diceSumTable = [] then diceSumTable.append((1,1)) for each dice combination.

You could also use a dictionary.

diceSumTable = {}
diceSumTable[2] = [(1,1)]
diceSumTable[3] = [(1,2),(2,1)]
#etc

You could then access by value rather than position.

>>>diceSumValue[3]
[(1,2),(2,1)]
>>>

Upvotes: 0

emvee
emvee

Reputation: 4449

As said, you start indexing the diceSumTable from index #2 onward, leaving entries 0 and 1 untouched. The error you got was because you were indexing past the end of the array.

For your problem a "dict" might be a better solution:

diceSumTable = {}
diceSumTable[ 2 ] = [(1,1)]
diceSumTable[ 3 ] = [(1,2), (2,1)]

Upvotes: 1

Andrew Jaffe
Andrew Jaffe

Reputation: 27077

You are confusing the value of an entry in a list with the index of a list.

diceSumTable[3] corresponds to the fourth entry in diceSumTable (since they are numbered from 0).

Your first line creates a list diceSumTable with 13 entries, numbered 0...12.

Your next set of lines fills in the 3d through 13th entries (and throws away what was there before!).

To do what you want, you have a few choices.

1/ You can do what you're doing, but ignore the first two entries. This is not very pythonic...

2/ You can create a length 11 list, holding the actual entries. In this case, the most efficient way to do it is

 diceSumTable = [] ### empty list
 diceSumTable.append([(1,1)])
 diceSumTable.append([(1,2),(2,1)])
 #### etc.

3/ You can use a dict. This is probably closest to what you want, although it's slightly inefficient in space and time, since you just want consecutive integer keys (but premature optimisation is the root of all evil):

diceSumTable = {} ### empty dict
diceSumTable[2] = [(1,1)]
diceSumTable[3] = [(1,2),(2,1)]
#### etc.

(Markdown question: is there any way to intersperse code within a bulleted or enumerated list?)

Upvotes: 0

Neel
Neel

Reputation: 21243

You are entering data from 2 index (means third element in array).

diceSumTable = [2,3,4,5,6,7,8,9,10,11,12,13,14]

when you do

# Replacing third element
diceSumTable[2] = [(1,1)]

diceSumTable will be like

diceSumTable = [2,3,[(1,1)],5,6,7,8,9,10,11,12,13,14]

Slly it will replace all values.

Upvotes: 0

BoshWash
BoshWash

Reputation: 5440

Try this:

def dice():

    diceSumTable = []  # define diceSumTable as a list
    diceSumTable.append((1,1))  # append the tuple to diceSumTable
    diceSumTable.append(((1,2),(2,1)))  # append a tuple of tuples to diceSumTable
    diceSumTable.append(((1,3),(2,2),(3,1)))
    diceSumTable.append(((1,4),(2,3),(3,2),(4,1)))
    diceSumTable.append(((1,5),(2,4),(3,3),(4,2),(5,1)))
    diceSumTable.append(((1,6),(2,5),(3,4),(4,3),(5,2),(6,1)))
    diceSumTable.append(((2,6),(3,5),(4,4),(5,3),(6,2)))
    diceSumTable.append(((3,6),(4,5),(5,4),(6,3)))
    diceSumTable.append(((4,6),(5,5),(6,4)))
    diceSumTable.append(((5,6),(6,5)))
    diceSumTable.append(((6,6)))

    #for illustrative purposes
    for i in diceSumTable:
        print i

dice()

You got 2, 3 because that's what you entered into the list in the first to places, the other numbers you put in got replaced with statements like diceSumTable[x] =.

Upvotes: 0

Related Questions