Search code examples
python-3.xmultidimensional-arrayindex-error

Trying to add to a 2d list, getting IndexError: tuple index out of range


I've written a function that will recursively go through a folder in the directory and add the contents of all .dat files to a two-dimensional list. Each column represents a file with each line on a new row. I'm using for loops to achieve this, but I'm getting IndexError: tuple index out of range when it tries to put this information into the list. I've looked at every way of getting this information into the list: appending, inserting and just assigning, but they all come out with similar errors.

def initialiseitems():
    items = ([], [])
    count = 0
    for root, dirs, files in os.walk("Bundles/Items/", topdown=False):
        for name in files:
            if os.path.splitext(os.path.basename(name))[1] == ".dat":
                if os.path.splitext(os.path.basename(name))[0] != "English":
                    prefile = open(os.path.join(root, name), "r")
                    file = prefile.readlines()
                    for lineNumber in range(0, sum(1 for line in file)):
                        line = file[lineNumber].replace('\n', '')
                        items[count].append(line)
                    count = count+1
    return items

It should just put them all in the array. It's evident the method of getting this into the list is wrong. What's the best way to do this? Preferably, with no external libraries. Thanks

Edit: Full error

Traceback (most recent call last):
  File "C:/Users/Kenzi/PycharmProjects/workshophelper/main.py", line 3, in <module>
items = initialisation.initialiseitems()
  File "C:\Users\Kenzi\PycharmProjects\workshophelper\initialisation.py", line 15, in initialiseitems
items[count].append(line)
IndexError: tuple index out of range

Solution

  • You have a logic problem.

    You are incrementing count = count+1 for any *.dat file that is not English.dat

    You use count to index into items = ([], []) which has exactly 2 elements.

    The third *.dat will create a count of 2 -your indexes are only 0 and 1 --> error.


    You can simplify your code:

    def initialiseitems():
        items = ([], [])
        count = 0
        for root, dirs, files in os.walk("Bundles/Items/", topdown=False):
            for name in files: 
                if name.endswith(".dat"):
                    if not name.startswith("English"):
                        fullname = os.path.join(root, name)
                        with open(fullname, "r") as f:
                            items[0].append( fullname )
                            items[1].append( [x.strip() for x in f.splitlines()]
    
        return items
    

    This returns a tuple (immutable object that contains 2 lists) - the first list contains the filenames, the second list the filecontent:

    (["file1","file2"],[ [ ...content of file 1...],[ ...content of file 2 ...]]
    

    The [ ...content of file 1...] is a list of lines without \n at it's ends.

    You can work with the result like so:

    result = initialiseitems()
    for filename,filecontent in zip (result[0],result[1]):
        # filename is a string like "path/path/path/filename"
        # filecontent is a list like [ line1, line2, line3, ...]