numb3rs1x
numb3rs1x

Reputation: 5213

python for loop tuple index out of range

I'm still trying to get the hang of python, so bear with me. please. I have this bit of code that I'm using from a book. The book does not properly show the white space in the code, so the spacing is my best guess. This code is supposed to break the results of a MySQL query into a more readable format.

if form is True:
columns_query = """DESCRIBE %s""" % (table)
print columns_query
columns_command = cursor.execute(columns_query)
headers = cursor.fetchall()
column_list = []
for record in headers:
    column_list.append(record[0])
output=""
for record in results:
    output = output + "===================================\n\n"
for field_no in xrange(0, len(column_list)):
    output = output + column_list[field_no] + ": " + str(record[field_no]) + "\n"
output = output + "\n"

When I try to run it, I get the following:

Traceback (most recent call last):
  File "odata_search.py", line 46, in <module>
    output = output + column_list[field_no] + ": " + str(record[field_no]) + "\n"
IndexError: tuple index out of range

It has something to do with the str(record[field_no]) portion of the code, but that's what it looks like in the book, so I'm not sure what else to try.

Upvotes: 1

Views: 4318

Answers (2)

numb3rs1x
numb3rs1x

Reputation: 5213

The problem it turns out was both the white space and, more importantly, the MySQL query itself. I was pulling a list that were rows in a column instead of pulling all columns of a row, which is what the loops were written to concatenate. The number of records I would get back in the result of the wrong query was not equal to the number of results in the list that contained all the columns. The code was also intended to be a loop within a loop, so the spacing I have at the top is wrong. It should look like it does below. I added a couple of lines before it to show the query I had to modify:

Old statement looped like this:

statement = """select %s from %s where %s like '%s' limit 10""" % (column, table, column, term)

Should look like this:

statement = """select * from %s where %s like '%s' limit 10""" % (table, column, term)

command = cursor.execute(statement)
results = cursor.fetchall()

column_list = []
for record in results:
    column_list.append(record[0])

Loop within a loop:

if form is True:
columns_query = """DESCRIBE %s""" % (table)
columns_command = cursor.execute(columns_query)
headers = cursor.fetchall()
column_list = []
for record in headers:
    column_list.append(record[0])
output=""
for record in results:
    output = output + "===================================\n\n"
    for field_no in xrange(0, len(column_list)):
        output = output + column_list[field_no] + ": " + str(record[field_no]) + "\n"
    output = output + "\n"

Upvotes: 0

mgilson
mgilson

Reputation: 309929

Clearly len(record) != len(column_list). (specifically, column_list is longer than record). Is there a reason that you expect them to be the same length?

One "fix" would be something like:

for col,rec in zip(column_list,record):
    output += col + ": " + str(rec) + "\n"

instead of:

for field_no in xrange(0, len(column_list)):
    output = output + column_list[field_no] + ": " + str(record[field_no]) + "\n"

This will truncate the output at the shorter of column_list and record.

I would recommend using zip instead of range(0,len(...)) in any event. It's much more idiomatic.

Upvotes: 1

Related Questions