Как не выйти за пределы массива python



Скачай курс
в приложении
Перейти в приложение
Открыть мобильную версию сайта
© 2013 — 2023. Stepik
Наши условия использования и конфиденциальности

Public user contributions licensed under cc-wiki license with attribution required
Как избежать ошибки выхода за пределы массива?
Задание:Беру текстовый файл на чтение в котором допустим a2b4c11 и переписываю исходный файл в файл где будет ааbbbbcccc. c.Больше двух цифр за буквой нет.
P.S.Был бы рад услышать ,как сделать код в котором после буквы может идти число с неограниченным количеством разрядов.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
out=[] j=1 i=0 with open ('C:\\Users\\Юзер\\Desktop\\Fele\\duta.txt','r+') as ouf: a=ouf.readline().strip() usf=[] ostf=[] y=0 for y in range(0,len(a)): if (a[y].isalpha()): usf.append(a[y]) elif (a[y].isdigit()) and (a[y+1].isdigit()): ostf.append(int(a[y])*10+int(a[y+1])) continue else: if a[(y-1)].isdigit()==False: ostf.append(a[y]) else: continue for i in range (0,len(usf)): out.append(usf[i]*int(ostf[j])) j+=1 ouf.write("".join(out))
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Как реализовать вычисления по формуле без ошибки выхода за пределы массива?
Пытаюсь реализовать формулу. Выдает ошибку:Индекс находился вне границ массива. int s; .
Обработка ошибки выхода за пределы Datagridview
Добрый день. Имеется таблица datagridview 10 на 10 и в этом поле генерируются цифры случайно и.
Почему нет ошибки выхода за пределы диапазона
StringBuilder str = new StringBuilder(); . if (str.Length > 0) str.Remove(0.
Не могу найти причину ошибки выхода за пределы диапазона
Подскажите где я ошибся Этот код работает как надо: using System; using.
709 / 348 / 120
Регистрация: 09.12.2020
Сообщений: 919
1 2 3 4
try: код except IndexError: что делать при ошибке
814 / 526 / 214
Регистрация: 22.12.2017
Сообщений: 1,495
Snibir,
1 2 3 4 5
import re s = 'a8b8o4b1a54' numbers = re.findall('(\d+)', s) chars = re.findall('([^0-9])', s) print(''.join([c * int(n) for (c,n) in zip(chars, numbers)]))
Добавлено через 6 минут
без re
1 2 3 4 5 6 7 8 9 10 11 12 13
s = 'a8b8o4b1a54' n = [] c = [] b = s[0] for i in s: if i.isdigit() and b.isdigit(): n[-1] += i elif i.isdigit(): n += i else: c += i b = i print(''.join([c * int(n) for (c, n) in zip(c, n)]))
Индексация, срезы, итерирование массивов
На этом занятии познакомимся со способами считывания и записи значений в массивы NumPy. В целом синтаксис очень похож на обращение к элементам списков языка Python. Давайте рассмотрим все на конкретных примерах. Предположим, что имеется одномерный массив:
a = np.arange(12) # array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
И мы хотим прочитать отдельные его элементы. Это можно сделать путем обращения к нужному элементу массива по его индексу, например, так:
a[2] # увидим значение 2

Помимо положительных индексов существуют еще и отрицательные, которые отсчитывают элементы с конца списка, например:
a[-1] # последнее значение 11 a[-2] # предпоследнее значение 10
Если мы выходит за пределы массива и указываем несуществующий индекс, то возникает исключение (ошибка):
a[12] # ошибка, последний индекс 11
Соответственно, если нужно изменить значение какого-либо элемента, то ему просто присваивается это новое значение:
a[0] = 100 # первый элемент равен 100
Как видите, здесь применяется тот же синтаксис, что и при работе с обычными списками Python. То же касается и срезов. Мы можем выделять и менять сразу группу элементов массива. Общий синтаксис срезов выглядит так:
Давайте посмотрим примеры использования этой конструкции:
b = a[2:4] # array([2, 3])
Здесь указан начальный индекс 2, конечный индекс 4 и по умолчанию берется шаг, равный 1. На выходе получаем массив из двух значений 2 и 3. Последний граничный индекс 4 не включается в срез.
Обратите внимание, в NumPy срезы возвращают новое представление того же самого массива, то есть, данные, на которые ссылаются переменные a и b одни и те же. Мы в этом можем легко убедиться, выполнив вот такую строчку:
b[0] = -100
и это приводит к изменению соответствующего элемента массива a:
array([ 100, 1, -100, 3, 4, 5, 6, 7, 8, 9, 10, 11])
Поэтому срезы – это не копии массивов, а лишь создание их нового представления. Это сделано специально для экономии памяти.
Другие примеры срезов:
a[3:] # array([ 3, 4, 5, 6, 7, 8, 9, 10, 11]) a[:5] # array([ 100, 1, -100, 3, 4]) a[-5: -1] # array([ 7, 8, 9, 10]) a[:] # array([ 100, 1, -100, 3, 4, 5, 6, 7, 8, 9, 10, 11]) a[1:6:2] # array([1, 3, 5]) a[::2] # array([ 100, -100, 4, 6, 8, 10]) a[::-1]# array([ 11, 10, 9, 8, 7, 6, 5, 4, 3, -100, 1, 100])
Я, думаю, общий принцип использования одномерных срезов понятен. Разумеется, срезам можно присваивать новые значения. Например, так:
a[:4] = [-1, -2, -3, -4] # присваивание списка Python a[4::2] = np.array([10, 20, 30, 40]) # присваивание массива NumPy
Элементы массива NumPy можно перебирать с помощью цикла for, так как массивы – итерируемые объекты. Например:
for x in a: print(x, sep=' ', end=' ')
Индексация и срезы многомерных массивов
В базовом варианте индексация и срезы многомерных массивов работают также как и в одномерных, только индексы указываются для каждой оси. Например, объявим двумерный массив:
x = np.array([(1, 2, 3), (10, 20, 30), (100, 200, 300)])

Для обращения к центральному значению 20 нужно выбрать вторую строку и второй столбец, имеем:
x[1, 1] # значение 20
Чтобы взять последнюю строку и последний столбец, можно использовать отрицательные индексы:
x[-1, -1] # значение 300
Если же указать только один индекс, то получим строку:
x[0] # array([1, 2, 3])
Эта запись эквивалентна следующей:
x[0, :] # array([1, 2, 3])
То есть, не указывая какие-либо индексы, NumPy автоматически подставляет вместо них полные срезы.
Для извлечения столбцов мы уже должны явно указать полный срез в качестве первого индекса:
x[:,1] # array([ 2, 20, 200])
Итерирование двумерных массивов можно выполнять с помощью вложенных циклов, например:
for row in x: for val in row: print(val, end=' ') print()
Если же необходимо просто перебрать все элементы многомерного массива, то можно использовать свойство flat:
for val in x.flat: print(val, end=' ')
У массивов более высокой размерности картина индексации, в целом выглядит похожим образом. Например, создадим четырехмерный массив:
a = np.arange(1, 82).reshape(3, 3, 3, 3)
Тогда для обращения к конкретному элементу следует указывать четыре индекса:
a[1, 2, 0, 1] # число 47
Для выделения многомерного среза, можно использовать такую запись:
a[:, 1, :, :] # матрица 3x3x3
a[0, 0] # двумерная матрица 3x3
Это эквивалентно записи:
a[0, 0, :, :]
Если же нужно задать два последних индекса, то полные срезы у первых двух осей указывать обязательно:
a[:, :, 1, 1] # матрица 3x3 a[0:2, 0:2, 1, 1] # матрица 2x2
Пакет NumPy позволяет множество полных подряд идущих срезов заменять троеточиями. Например, вместо a[:, :, 1, 1] можно использовать запись:
a[. , 1, 1] # эквивалент a[:, :, 1, 1]
Это бывает удобно, когда у массива много размерностей и нам нужны последние индексы.
Списочная индексация
Помимо указания у массивов обычных индексов или срезов в NumPy существует еще один способ индексирования – через списки или массивы целых чисел. Чтобы лучше понять, о чем идет речь, рассмотрим этот механизм на примерах. Для простоты возьмем одномерный массив с какими-нибудь значениями:
a = np.arange(1, 9) # array([1, 2, 3, 4, 5, 6, 7, 8])
Далее, смотрите, если указать обычный числовой индекс, то получим одно значение соответствующего элемента:
a[0] # значение 1
Но, если вместо числового индекса указать список:
b = a[[0]] # array([1])
то на выходе уже получим копию массива из одного первого значения исходного. То есть, выполняя далее операцию:
b[0] = 100
Изменение массива b не приведет к изменению данных в массиве a.
А что будет, если в списке указать несколько индексов? Например, так:
a[[0, 1, 7, 5]] # array([1, 2, 8, 6])
На выходе получаем новый массив, состоящий из соответствующих значений. Или, можно сделать даже так:
a[[0, 0, 1, 1, 1, 2, 3, 4, 5, 6, 7]] # array([1, 1, 2, 2, 2, 3, 4, 5, 6, 7, 8])
То есть, мы здесь имеем, фактически, способ формирования новых массивов на основе других массивов. В списке достаточно перечислить индексы нужных элементов и на выходе формируется массив с соответствующими значениями. В ряде случаев такая операция бывает очень удобной.
Но здесь есть один важный нюанс. Копия массива через списочное индексирование создается, когда выражение записано справа от бинарного оператора (является выражением типа rvalue). Если же такую же конструкцию записать слева от оператора (как выражение lvalue), например, присваивания:
a[[0, 1, 2]] = [10, 20, 30]
то копия не создается, а просто в элементы этого же массива с индексами 0, 1 и 2 заносятся значения 10, 20 и 30. Далее в этом же занятии мы подробнее увидим различные варианты и особенности при присваивании значений через списочное индексирование.
Кроме обычных списков языка Python мы можем передавать и массивы NumPy, состоящие из целых значений. Например, так:
indx = np.array([0, 0, 1, 1, 1, 2]) a[indx] # array([1, 1, 2, 2, 2, 3])
Или, с булевыми значениями:
bIndx = [True, True, False, False, False, True, False, False] a[bIndx] # array([1, 2, 6])
В результате останутся только те элементы, которым соответствуют индексы True. Причем, длина списка (или массива) bIndx должна совпадать с длиной массива a, иначе произойдет ошибка.
Последний вариант списочной индексации используется очень часто. Например, мы можем сформировать массив индексов путем какой-либо булевой операции над массивом:
i = a > 5 # array([False, False, False, False, False, True, True, True])
А, затем, использовать его, чтобы оставить только нужные элементы:
a[i] # array([6, 7, 8])
Или, все это можно записать короче в одну строчку:
a[a > 5] # array([6, 7, 8])
Как видите, это невероятно удобный механизм обработки данных массивов пакета NumPy.
Списочная индексация и многомерные массивы
Фактически, массив индексов определяет значения и форму создаваемого массива. Например, если взять тот же одномерный массив:
a = np.arange(1, 9)
но набор индексов определить как двумерный массив:
i = np.array([[0, 1], [2, 3]])
то на выходе будет формироваться уже двумерный массив:
a[i] # array([[1, 2], [3, 4]])
Только в этом случае индексы i должны определяться именно массивом NumPy, а не списком Python.
Так можно создавать массивы любых размерностей. Давайте теперь посмотрим, как будет себя вести списочное индексирование с многомерными массивами. Возьмем двумерный массив:
a = np.arange(1, 13).reshape(3, 4)
и одномерный список индексов:
indx = [2, 1, 0] a[indx]
На выходе получим массив:
array([[ 9, 10, 11, 12],
[ 5, 6, 7, 8],
[ 1, 2, 3, 4]])
Смотрите, здесь индексы обозначают номера строк двумерного массива. В результате, строки нового массива идут в обратном порядке. Далее, пропишем индексы в виде двумерного массива:
indx = np.array([[1, 0], [2, 1]]) a[indx]
Результатом будет трехмерный массив:
array([[[ 5, 6, 7, 8],
[ 1, 2, 3, 4]],
[[ 9, 10, 11, 12],
[ 5, 6, 7, 8]]])
Что здесь произошло? В действительности, каждый индекс двумерного массива соответствует определенной строке этого массива. А двумерная форма индексов лишь указывает как упаковать строки в новом массиве. То есть, вместо каждого индекса подставляется своя строка и получается трехмерный массив.
Если же мы хотим выбирать из двумерного массива не строки, а отдельные элементы и на их основе формировать новые массивы, то следует использовать два списка. Первый список по прежнему будет указывать строки массива, а второй – индексы столбцов у каждой строки. Например, так:
i0 = [0, 1] i1 = [1, 2] a[i0, i1] # array([2, 7])
Работу такого списочного индексирования можно представить в виде:

При множественной списочной индексации допускается указывать конкретные индексы и срезы. Например:
a[:, i1]
В этом случае получим уже матрицу 3×2, то есть, второй список i1 здесь используется для выделения столбцов целиком, а не одного только элемента. Соответственно, строчка:
a[i0, 1] # array([2, 6])
выделим массив из двух значений 2 и 6.
Изменение массивов через списочную индексацию
С помощью списков можно не только создавать новые массивы, но и менять значения в исходном. Например, возьмем одномерный массив:
a = np.arange(7) # array([0, 1, 2, 3, 4, 5, 6])
и изменим его следующие элементы:
a[[0, 4, 6]] = [-1, -2, -3] # array([-1, 1, 2, 3, -2, 5, -3])
Смотрите, как это удобно. Мы сразу списком индексов обозначаем изменяемые элементы и присваиваем им соответствующие новые значения.
Если в списке индексов имеются повторы, то новое значение будет соответствовать последнему значению:
a[[0, 0, 0, 1]] = [1, 2, 3, 100] # array([ 3, 100, 2, 3, -2, 5, -3])
Здесь в первый элемент (с индексом 0), в итоге, запишется число 3. Или можно выполнить вот такую операцию:
a[[0, 0, 0]] = a[[0, 0, 0]] + 3
Здесь сначала будет выполнена операция списочного индексирования a[[0, 0, 0]], а уже потом добавлено значение 3. То есть, это запись эквивалентна следующей:
a[0] = a[0] + 3
Аналогично все выполняется и при такой команде:
a[[0, 0, 1, 2]] += 1 # array([ 7, 101, 3, 3, -2, 5, -3])
Она эквивалента записи:
a[[0, 1, 2]] += 1 # array([ 7, 101, 3, 3, -2, 5, -3])
Соответственно, элементам с индексами 0, 1 и 2 будет прибавлена 1. Вот этот момент следует иметь в виду при работе с массивами NumPy.
Те же самые математические операции и операции присваивания можно выполнять и с многомерными массивами. Работает все аналогичным образом. Вот так вот работают индексы, срезы и списочное индексирование в пакете NumPy.
Видео по теме

#1. Пакет numpy — установка и первое знакомство | NumPy уроки

#2. Основные типы данных. Создание массивов функцией array() | NumPy уроки

#3. Функции автозаполнения, создания матриц и числовых диапазонов | NumPy уроки

#4. Свойства и представления массивов, создание их копий | NumPy уроки

#5. Изменение формы массивов, добавление и удаление осей | NumPy уроки

#6. Объединение и разделение массивов | NumPy уроки

#7. Индексация, срезы, итерирование массивов | NumPy уроки

#8. Базовые математические операции над массивами | NumPy уроки

#9. Булевы операции и функции, значения inf и nan | NumPy уроки

#10. Базовые математические функции | NumPy уроки

#11. Произведение матриц и векторов, элементы линейной алгебры | NumPy уроки

#12. Множества (unique) и операции над ними | NumPy уроки

#13. Транслирование массивов | NumPy уроки
© 2023 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта
Как не выйти за пределы списка? Python
Мое задание: Ваша задача состоит в том, чтобы суммировать различия между последовательными парами в массиве в порядке убывания. Пример [2, 1, 10] —> 9 В порядке убывания: [10, 2, 1] Сумма: (10 — 2) + (2 — 1) = 8 + 1 = 9 Если массив пуст или массив имеет только один элемент, результатом должно быть: 0 Вот мой код:
a = sorted(arr)[::-1] b = [a[i:i+2] for i in range(len(a)-1)] c = [] for i in range(len(b)): for j in range(len(b[i])): try: c.append(int(b[i][j]-b[i][j+1])) except IndexError: break return sum(c)
Постоянно спасаюсь try, exept чтобы не вылезать за пределы, возможны другие способы?
Отслеживать
задан 6 июл 2022 в 16:37
591 1 1 золотой знак 4 4 серебряных знака 20 20 бронзовых знаков
меня просто похоронило решение человека написавшего: return max(arr) — min(arr) if arr else 0
6 июл 2022 в 16:39
за пределы чего? и в чем конкретная проблема?
6 июл 2022 в 16:39
как например zip или что то подобное использовать не пойму, можно пример? проблема постоянно лезу за массив через вложенный цикл, может функции есть готовые?
6 июл 2022 в 16:41
Так вы просто напишите корректный код, чтобы не вылезать за пределы. for j in range(len(b[i])) — вот здесь значение j может принимать значения 0 и 1 . b[i][j+1] — вот здесь j+1 это 1+1 = 2 — получился выход за пределы
6 июл 2022 в 16:43
@Сергей Решение из первого комментария работает при единичной длине
6 июл 2022 в 17:29
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Вашу задачу можно решить куда проще, и для этого не понадобится никаких try-except — если, конечно, они не требуются в ТЗ.
- Сортируем исходный массив в порядке убывания (можно тот же, arr , можно другой, я буду использовать arr ).
- Создаём отдельную переменную s — сумматор соответствующих разностей пар.
- Проходим одним циклом через все индексы от первого и последнего не включая, с ним берём текущий и предыдущий элементы массива и вычисляем разность. Так как массив уже отсортирован по убыванию, то модуль необязателен.
- Все получившиеся текущие разности суммируем с s .
- После цикла выводим сумму.
arr = [2, 1, 10] # сортируем в убывающем порядке: # https://pythonz.net/references/named/list.sort/ arr.sort(reverse = True) s = 0 for i in range(1, len(arr)): s += arr[i - 1] - arr[i] print(s) # 9
Как видите, мы обходимся всего лишь одним циклом и массивом и заметно упрощаем программу для понимания и использования 🙂
Отслеживать
ответ дан 6 июл 2022 в 17:06
3,908 4 4 золотых знака 9 9 серебряных знаков 22 22 бронзовых знака
а зачем это вообще — что это дает-то? Я так и написал ранее: «Даже если не вычитать из максимума минимум, то можно внутри отсортированного списка последовательно с его элементами работать. » Но есть и проще — return max(arr) — min(arr) if arr else 0
6 июл 2022 в 17:40
@Сергей тот комментарий я не прочёл; вариант с разностью максимума и минимума, действительно, валиден