Попытка добавить в 2d список, выводя IndexError: tuple index вне диапазона - PullRequest
0 голосов
/ 06 января 2019

Я написал функцию, которая рекурсивно просматривает папку в каталоге и добавляет содержимое всех файлов .dat в двумерный список. Каждый столбец представляет файл с каждой строкой в ​​новой строке. Я использую циклы for для достижения этой цели, но я получаю IndexError: tuple index out of range, когда он пытается поместить эту информацию в список. Я посмотрел на все способы получения этой информации в списке: добавление, вставка и просто назначение, но все они имеют схожие ошибки.

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

Нужно просто поместить их все в массив. Очевидно, что метод внесения этого в список неверен. Какой лучший способ сделать это? Желательно, без внешних библиотек. Спасибо

Редактировать: Полная ошибка

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

Ответы [ 2 ]

0 голосов
/ 06 января 2019

items = ([], []) объявлял список кортежем, а не списком. Не знаю, что это такое, но здесь это не работает. Я изменил его на items = [] вместо этого.

Кроме того, циклы for, которые я настроил для помещения файлов в массив, были неэффективными. Я уже загрузил файл в список 1d, открыв его и присвоив переменной, поэтому добавление этой переменной 1d к items фактически добавляет весь столбец. Кроме того, прочитайте пост Патрика - я ограничил список, который пытался объявить, только двумя столбцами / строками. не хорошо.

Код теперь выглядит так:

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()
                items.append(file)
return items

Также, спасибо Джеку за исправление моей грамматики.

0 голосов
/ 06 января 2019

У вас логическая проблема.

Вы увеличиваете count = count+1 для любого *.dat файла, который не English.dat

Вы используете count для индексации в items = ([], []), который имеет ровно 2 элемента.

Третий *.dat создаст счет из 2-х ваших индексов, только 0 и 1 -> ошибка.


Вы можете упростить свой код:

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

Возвращает кортеж (неизменный объект, который содержит 2 списка) - первый список содержит имена файлов, второй список содержимого файла:

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

[ ...content of file 1...] - список строк без \n на его концах.

Вы можете работать с результатом примерно так:

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, ...] 
...