Search code examples
pythonsqlitefor-loopwhile-loopindex-error

For-in-loop Multidimensional list IndexError


I am getting a list IndexError: list index out of range. The following is my code

def email_address_grab(email_list):
    """ This function takes in a list of emails and puts them into a sql database""" 
    
    # import module
    import sqlite3 as sql

    # Setup sql
    # create connection for sql
    connection = sql.connect("emailList.db")

    # create cursor
    crsr = connection.cursor()

    # create sql table
    cmd = """CREATE TABLE emails (
    email_handle TEXT,
    email_domain VARCHAR(20));"""
    crsr.execute(cmd)


    # iterate through email list
    for index, email in enumerate(email_list):
        #split email with a delimiter of "@"
        email_list[index] = email.split('@')

    # while loop to put all data into table
    ct = 1
    index = 0
    while ct <= len(email_list):
        for i in email_list:
            for j in i:
                email_address_1 = email_list[index][index]
                email_address_2 = email_list[index][index + 1]
                cmd = f"""INSERT INTO emails (email_handle, email_domain) VALUES ("{email_address_1}", "{email_address_2}");"""
                crsr.execute(cmd)
                index += 1
                #print(cmd)
        ct += 1


    # get the contents of the table
    crsr.execute("SELECT * FROM emails;")
    
    # store contents in a variable
    email_address_list = crsr.fetchall()

    # save changes to sql table
    connection.commit()

    # close connection
    connection.close()

    # return print statement for data
    # return print(email_address_list)

Error:

Traceback (most recent call last):

  File "c:/Users/USER/Desktop/email grabber.py", line 78, in <module>
    email_address_grab(["test@gmail.com", "test2@gmail.com"])
  File "c:/Users/USER/Desktop/email grabber.py", line 53, in email_address_grab
    email_address_2 = email_list[index][index + 1]

IndexError: list index out of range

Solution

  • You shouldn't be using index in the second subscript in

                    email_address_1 = email_list[index][index]
                    email_address_2 = email_list[index][index + 1]
    

    Each element of email_list[index] only has two elements, the handle and domain. It mkaes no sense to use the index in the main list as the index into the nested list.

    What you want is:

    email_address_1, email_address_2 = email_list[index]
    

    Actually, the entire loop is unnecessary. Use executemany() with placeholders and it will automatically loop over the list.

    cmd = "INSERT INTO emails (email_handle, email_domain) VALUES (?, ?);"
    crsr.executemany(cmd, email_list)