Индекс вне диапазона путаницы - PullRequest
0 голосов
/ 22 февраля 2020

Итак, я новичок в программировании, и у меня проблемы с индексом вне диапазона ошибок. Быстрый пример:

У меня есть список, lst = (5,7,8,9,10).

Я хочу удалить каждое четное число и каждое число справа от четного числа.

Я бы подошел к этой проблеме, получив индекс каждого четного числа, 'i', и удаление lst[i] и lst [i+1]. Это не будет работать, если последнее число четное, потому что после последнего элемента в списке нет lst [i+1].

Я столкнулся с этой проблемой по нескольким основным c проблемам, над которыми я работал. Мой подход к решению этой проблемы, вероятно, неверен, поэтому я хотел бы знать:

  1. Как я могу / могу ли я решить проблему таким образом, является ли она эффективной или нет?
  2. Что было бы наиболее эффективным способом решения этой проблемы?

Ответы [ 3 ]

1 голос
/ 22 февраля 2020

Добро пожаловать в клуб! Программирование - это очень весело, и вы всегда можете улучшить его с постепенным прогрессом. Я постараюсь быть исчерпывающим со своим ответом.

Со списками (также известными как массивы) помните, что список и его индексы начинаются с нуля. Это означает, что индексы массива начинаются с номера 0 (а не с номера 1, как вы бы это делали при обычном подсчете).

arr = [5, 7, 8, 9, 10]

# If you want to access the first element of the array
# then you would use the 0 index. If you want the Second
# element you use index 1.

print(arr[0]) # prints 5 or the 1st element
print(arr[1]) # prints 7 or the 2nd element

Я бы не стал использовать вашу методику циклического повторения как для или в этом случае потому что вы удаляете элементы, вы идете для массива. Если вы удаляете элемент во время зацикливания, вы изменяете длину массива.

Вместо этого вы можете создать новый массив из зацикливания и только добавлять или добавлять нечетные значения в этот новый массив.

arr = [5, 7, 8, 9, 10]
new_arr = []

for idx, val in enumerate(arr):
    if idx % 2 == 1:
        new_arr.append(val)
return new_arr # yields [7,9] or this process creates a new array of odd elements

Кроме того, помните, что когда вы используете [i+1] при индексировании с помощью l oop, имеет смысл остановить элемент l oop на ранней стадии, чтобы избежать ошибки выхода за пределы индекса. .

Сделайте это (без ошибок)

for idx in range(len(arr)-1):
    # pseudocode
    print(arr[i] + arr[i+1])

вместо этого (ошибка индекса). Причина в том, что в последнем элементе, если вы попытаетесь добавить 1 к последнему индексу, а затем получите доступ к несуществующему значению, будет возвращена ошибка:

for idx in range(len(arr)):
    # pseudocode
    print(arr[i] + arr[i+1])
arr = [5, 7, 8, 9, 10]
# if you try to access arr[5]
# you will get an error because the index 
# and element do not exist
# the last element of arr is arr[4] or arr[-1]
arr[5] # yields an out of index error

Существует много Pythoni c (почти как в разговорной фразе, определяющей c до python) способы достижения sh вашей цели, которые более эффективны ниже.

Вы можете использовать нарезку, интервал и del (удалить оценку) ) для удаления четных числовых элементов

>>> arr = [5, 7, 8, 9, 10]
>>> del arr[::2] # delete even numbers # if you wanted to delete odd numbers del arr[1::2]
>>> arr
[7, 9]

Или понимание списка для создания нового списка при циклическом выполнении некоторого условия для фильтрации четных чисел:

new_arr = [elem for idx, elem in enumerate(arr) if idx % 2 == 0]

Используется оператор% чтобы увидеть, есть ли остаток от деления. Таким образом, если idx равен 10. Тогда 10% 2 == 0 истинно, потому что 2 может делиться на 10 пять раз, а остаток равен 0. Следовательно, элемент является четным. Если бы вы проверяли на нечетность, то условие было бы:

idx % 2 == 1

Более подробное объяснение этих Python методов можно найти в этом великом посте переполнения стека здесь

1 голос
/ 22 февраля 2020

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

Вот пример того, как вы можете выполнить sh то, что вы ищете:

myList = [5, 7, 8, 9, 10]

# use list comprehension to get indexes of even numbers into a list.
# num % 2 uses the modulus operator to find numbers divisible by 2
# with a remainder of 0.
even_number_indexes = [idx for idx, num in enumerate(myList) if num % 2 == 0]
# even_number_indexes: [2, 4]

# sort our new list descending
even_number_indexes.reverse()
# even_number_indexes: [4, 2]

# iterate over even_number_indexes and delete index and index + 1
# from myList by specifying a range [index:index + 2]
for index in even_number_indexes:
    del myList[index:index + 2]


print(myList)

вывод: [5, 7]

0 голосов
/ 22 февраля 2020

Вы можете проверить, превышает ли i+1 (Изменить: или равен) длину списка, и если это так, не выполнять код.

Вы также можете обработать это в блоке try / Кроме.

Что касается эффективности этого метода решения, мне кажется, хорошо. Одним из недостатков в этом подходе является то, что люди пытаются перебирать список при его изменении, что может привести к неизвестным ошибкам. Если вы используете функцию remove(), вы, вероятно, захотите сделать это с копией списка.

...