1

I'm trying to get certain data in columns from my MySQL database but I get this error when trying to index a list in a for loop. Everything works well until I'm trying to print out data from 1 column.

Here's the list. I do believe this is a tuple but that shouldn't be the problem. (I think)

(1, 'Router', '192.168.1.1', '80')

Here's my code:

myresult = mycursor.fetchall()
            for x in myresult:
                print(x)
                time.sleep(0.2)
            ip = myresult[2]
            print(ip)

This is the IndexError:

.....
File "directory..", line 172, in huvudmeny2
    ip = myresult[2]
IndexError: list index out of range

Process finished with exit code 1

How can it be out of range when it has 4 items?

7
  • fetchall() returns a list of tuples not a single tuple. If you have only one result, that will be a list with one item (which will be the the tuple in question). Your ip is probably at x[2] for each result. Commented Feb 15, 2021 at 23:05
  • How many actual rows are being found by this query? Because myresult[2] is trying to get the third row of the results. Commented Feb 15, 2021 at 23:06
  • Oh, I see! Is there any other way I could access the IP column? Thanks for the quick reply.@MarkM Commented Feb 15, 2021 at 23:09
  • 1
    @redeliish if you only expect one row, maybe fetchone() is a better choice here. Then you just get the tuple you are looking for and can index it the way you like. Commented Feb 15, 2021 at 23:20
  • 1
    @MarkM, that's a good idea, I've added it to the accepted answer. The only caveat is that you need to watch out for an empty result set, but OP has to do that anyway, even for fetchall. Commented Feb 16, 2021 at 1:16

2 Answers 2

1

The fetchall method returns a list of the remaining rows, each a tuple. It does not return the tuple.

Hence there's a good chance you got less than three rows.

If you want the IP address of the first row from the query (for example), that would be:

myresult[0][2]

The following transcript shows this in action (after dummying up some data):

>>> myresult = [(1, 'Router', '192.168.1.1', '80')]

>>> print(myresult)
[(1, 'Router', '192.168.1.1', '80')]

>>> print(myresult[2])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

>>> print(myresult[0][2])
192.168.1.1

An alternative, if you know there will only be one row of useful data, is to use fetchone instead of fetchall. This actually returns a single tuple rather than a list of tuples, so you can use your original indexing method. You just need to check for None first since that's what you'll get if there were no rows returned.

But you already have that problem since you're not checking for an empty list in your original code, which is what fetchall gives you when there are no rows.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, answered my question. So a small recap.. the "[0]" is targeting the row and [2] is targeting the index item? Correct me if I'm wrong!
@redeliish: I will correct you if you're wrong, that's in my nature. However, since you're right, all I can do is applaud you for understanding :-)
1

fetchall() returns a list, so you are printing index 2 of this list.

maybe you want something like:

for x in myresult:
  print(x)
  time.sleep(0.2)
ip = myresult[0][2]
print(ip)

So you will access the 1st element of the list of tuples, then access the element you want.

You also can put the last 2 lines in the for loop to make sure they exist, like so:

for x in myresult:
  print(x)
  time.sleep(0.2)
  ip = myresult[2]
  print(ip)

Comments

Your Answer

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.