обработка списка приводит к ошибке «индексы списка должны быть целыми числами или слайсами, а не кортежем» - PullRequest
2 голосов
/ 02 апреля 2019

Этот код предназначен для того, чтобы принимать строку в качестве входных данных, а затем генерировать 2d массив частоты появления букв друг за другом. Таким образом, для каждой итерации увеличивается значение целого числа в массиве (например, HI будет [h][i] =+ 1).

Моя проблема - сообщение об ошибке

list indices must be integers or slices, not tuple

появляется, когда я запускаю приведенный ниже код. Я изменил способ создания массива, поэтому теперь он создается в виде списка, что подтверждается при переходе в режим отладки (letterArray становится списком списков.)

Причина, по которой я преобразую букву в ASCII, заключается в том, что я могу сравнить ее с другими значениями ASCII, чтобы очистить строку одновременно. Я намерен преобразовать строку в нижний регистр позже.

Я попытался преобразовать letterArray в список, хотя это ничего не меняет, так как letterArray является списком. Я не могу найти какую-либо соответствующую информацию на 2d массиве с той же проблемой.

inputString = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat'  #just a test string
inputStringArray = list(inputString)        #break into char arrray
letterArray = []
posY = 28
x=0

for i in range(26):             #create balnk list of 0s of size 26x26
    letterArray.append([])
    for j in range(26):
        letterArray[i].append(0)

for letter in inputStringArray:
    posX = ord(letter)-97                   #-97 so that a = 0, z = 25
    if posY is 28 and posX <= 26 and posX >= 0:                     #instantiate first instance of past letter
        posY = posX
        continue
    if posX <= 26 and posX >= 0:                #if the char is a letter
        x = letterArray[posY,posX]
        x +=1
        letterArray[posY,posX] = x             #increment the space in the array by 1
        posY = posX
    else:
        continue

Точная ошибка:

Message=list indices must be integers or slices, not tuple
  Source=C:\Users\me\source\repos\InputRecorder\InputRecorder\Recording.py
StackTrace:
  File "C:\Users\me\source\repos\InputRecorder\InputRecorder\Recording.py", line 103, in KeysToArray
    x = letterArray[posY,posX]

Есть предложения?

Ответы [ 2 ]

2 голосов
/ 02 апреля 2019

Вы создали вложенный список, доступ к которому можно получить с помощью следующего синтаксиса:

x = letterArray[posY][posX]
0 голосов
/ 02 апреля 2019

Я вижу, что есть ответ, который решает ваше сообщение об ошибке, но я хочу дать несколько советов по улучшению вашего кода.

Здесь f1() - ваш код, а f2() - мое улучшенное предложение;в нем меньше кода, на мой взгляд, он более понятен и требует гораздо меньше времени для запуска.

def f1(inputString):
    inputStringArray = list(inputString)            # break into char arrray
    letterArray = []
    posY = 28

    for i in range(26):                             # create balnk list of 0s of size 26x26
        letterArray.append([])
        for j in range(26):
            letterArray[i].append(0)

    for letter in inputStringArray:
        posX = ord(letter)-97                       # -97 so that a = 0, z = 25
        if posY is 28 and posX <= 26 and posX >= 0: # instantiate first instance of past letter
            posY = posX
            continue

        if posX <= 26 and posX >= 0:                # if the char is a letter
            x = letterArray[posY][posX]
            x +=1
            letterArray[posY][posX] = x             # increment the space in the array by 1
            posY = posX
        else:
            continue

    return letterArray

def f2(input_str):
    max_n = 26

    # build nested lists with zeros
    letter_list = [
        [0, ] * max_n
        for _ in range(max_n)]

    # 'None' is usually used to indicate an invalid value
    prev_i = None

    for letter in input_str:
        curr_i = ord(letter) - 97

        if 0 <= curr_i <= max_n:
            if prev_i is not None:
                letter_list[prev_i][curr_i] += 1

            prev_i = curr_i

    return letter_list

Утверждение, что результаты совпадают:

>>> s = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat'
>>> r1 = f1(s)
>>> r2 = f2(s)
>>> r1 == r2
True

Сравнение времени выполнения (f2 занимает половину времени f1 для этого образца ввода):

>>> import timeit
>>> timeit.timeit('f1(s)', 'from __main__ import f1, s', number=10000)
1.0122240540222265
>>> timeit.timeit('f2(s)', 'from __main__ import f2, s', number=10000)
0.4270052219508216
...