简体   繁体   中英

error in python: list assignment index out of range

I searched everywhere and even though there were a couple of questions and answers regarding this error I couldn't find a solution to fix my problem

I'm reading in from a file that contains letters and numbers and I'm populating my matrix depending on the values in that file. ex: file description of letters and numbers ... table:

  a b c d 
a 1 2 5 6
b 5 6 3 4 
c 3 2 1 4 
d 2 4 6 8 

Here's the code

matrix = [[0 for j in range(4)] for i in range(4)]
i = 0
j = 0

for line in file:
   for a in line:
      if is_number(a):
         matrix[i][j] = int(a)
         j+= 1
      if matrix.count(0) < 2: #since matrix already populated with zeroes. it shouldn't have 
                               #many per program specifications, that's why I use this 
                               #conditional to increment i and reset j back to 0
         i += 1
         j = 0

file.close()

I don't understand why I keep getting that error.

I see two possible ways you could end up with an IndexError in your code.

The first problem occurs because of the way you are iterating through the file that you're reading. Your code:

for line in file:
    for a in line:
        if is_number(a):
            # do stuff

Reads a line in the file into the variable line . Then, each character is stored in the variable a and you check if it is a number. If any of the integers you are reading in are greater than 9 you will see an IndexError since it will count each digit as a separate number, causing you to eventually run out of room in your pre-allocated array.

A possible fix would be to change the line:

for a in line:

to

for a in line.split()

which will split the line into a list of words (that is, a new entry for everything separated by whitespace). So, "6 12 4 5" will become [6,12,4,5] , making it so that you don't count the 1 and 2 in 12 separately.

The second issue I see with your code is in the line:

if matrix.count(0) < 2:

If your input file ever contains a zero, it will cause this line to stay true for one iteration of the loop longer than you would like. A possible fix would be to change the line to:

if j == len(matrix[0]) - 1:

try something like this:

with open("data1.txt") as f:
    next(f)                  #skip the first line
    lis=[map(int,x.split()[1:]) for x in f]  #use x.split()[1:] to remove the alphabet
    print lis

output:

[[1, 2, 5, 6], [5, 6, 3, 4], [3, 2, 1, 4], [2, 4, 6, 8]]

If you know the input file already has the right matrix (line by line) layout you could use the following :

matrix = filter(lambda x: len(x)>0, [[int(a) for a in l.split() if is_number(a)] for l in file])

If you cannot expect anything from the input layout, you could try:

data = open("test").read()
l = filter(lambda x: is_number(x), data.replace("\n"," ").split())
width = int(math.sqrt(len(l)))
print [[int(l[i+width*j]) for i in range(width)] for j in range(width)]           

You're constructing a 4x4 matrix in the first line of code, but your data is a 6x6 matrix. When you try to store an element at index 4 in row 0, you get an IndexError .

The problem is here:

matrix = [[0 for j in range(4)] for i in range(4)]

Your matrix is 6x6, but your code only compensates for a 4x4 matrix.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM