Python: нарезка итерируемых объектов

Термин нарезка в программировании обычно относится к получению подстроки, подкортежа или подсписка из строки, кортежа или списка соответственно.
Python предлагает множество простых способов разрезать не только эти три, но и любые итерируемые объекты. Итерация, как следует из названия, любой объект, который может повторяться.
В этой статье мы рассмотрим все, что вам нужно знать о нарезке списков в Python.
Нарезка списка в Python
Есть несколько способов разрезать список, наиболее распространенным из которых является использование оператора : со следующим синтаксисом:
Параметр start представляет собой начальный индекс, end это конечный индекс, и step это количество элементов в шаге.
Если step явно не указано, используется значение по умолчанию 1 . Обратите внимание, что элемент с индексом start будет включен в результирующий подсписок, а элемент с индексом end не будет. Первый элемент списка имеет индекс 0 .
Пример без параметра step :
Это должно напечатать:
Для того, чтобы получить слова через одно, установите step на 2 :
Если step нет в списке, подсписок будет начинаться с начала. Аналогичным образом, если end нет в списке, подсписок будет заканчиваться концом исходного списка:
Этот фрагмент кода распечатывает:
Нахождение начала и конца списка с помощью среза
Обозначение среза может также использоваться с отрицательной индексацией. Отрицательное индексирование работает так же, как обычное индексирование, за исключением того факта, что оно начинает индексирование с последнего элемента, имеющего индекс -1 .
Его можно использовать для получения начала и конца списка заданной длины. Голова списка — это подсписок, который содержит первые n элементы списка, а хвост — подсписок, содержащий последние n элементы.
Давайте продолжим и разделим хвост и начало списка:
Использование нотации среза для переворота списка
Даже параметр step может быть отрицательным. Если мы установим отрицательное значение, результирующий список будет перевернут со значением step . Вместо того, чтобы идти вперед, мы делаем шаг назад, от конца списка к началу и включаем следующие элементы:
Замена элементов подсписка нотацией среза
Обозначение среза может использоваться для присвоения новых значений элементам определенного подсписка. Например, давайте попробуем заменить хвост и начало списка:
Замена каждого n-го элемента списка срезной нотацией
Простой способ заменить каждый n-й элемент списка — установить для параметра step значение n в нотации среза:
Вывод
Нарезать любую последовательность в Python легко, просто и интуитивно понятно. Отрицательная индексация предлагает простой способ получить первые или последние несколько элементов последовательности или изменить ее порядок.
В этой статье мы рассмотрели, как применить нотацию фрагментов к спискам в Python.
7 часто встречающихся вопросов про списки Python
В данной статье мы предложим вам простые, легкие для понимания решения, а также некоторые советы и рекомендации, которые вы сможете проверить самостоятельно.
Список вопросов, на которые мы ответим в данной статье
Предварительные сведения
Списки в Python это на редкость популярная тема как для начинающих свой путь программировании, так и для опытных экспертов в языке Python. Если верить Google Trends, то интерес к этой теме растет из года в год.
Если вы регулярно посещаете форумы, где можно задать вопросы по программированию на Python, например Stack Overflow, Quora или Reddit, то наверняка понимаете причину такой популярности этой темы.
На этих форумах постоянно появляется множество вопросов про списки, за них голосуют, и наиболее интересные продолжают обсуждать, находя разные решения.
В данной статье мы кратко пройдемся по самым распространенным вопросам на тему списков в языке Python.
Что такое списки в Python?
Списки, наряду со словарями, кортежами и множествами, это одна из четырех встроенных в Python структур данных. Списки используются для хранения упорядоченных коллекций элементов. Сами элементы при этом могут быть разных типов, но, как правило, все же имеют один и тот же тип. Эти элементы помещены в квадратные скобки и разделены запятыми. Вот пример таких списков:
Можно заметить, что список, хранящийся во второй переменной biggerZoo , похож на список из первой переменной zoo , первые четыре элемента совпадают. Но он также содержит в себе список с названиями обезьян.
Поскольку списки в Python хранят упорядоченные коллекции элементов или объектов, мы можем сказать, что они относятся к последовательностям и имеют все признаки и поведение таковых. Типами последовательностей также считаются строки и кортежи.
Вы можете спросить, что такого особенного в типах последовательностей. Ну, попросту говоря, это означает, что программа может их перебирать! Вот почему списки, строки, кортежи и множества часто называют «итерирующими последовательностями».
Имейте в виду, что эта концепция очень важна. Вы можете увидеть ее использование и в других языках программирования, которые применяются в работе с данными, например в Scala!
Теперь давайте перейдем к делу и углубимся в исследование наиболее интересных вопросов про списки в Python.
1. В каких ситуациях лучше использовать списки, а в каких кортежи, словари или множества?
Материал во введении кажется довольно простым, когда вы просто читаете его, но когда вы на самом деле работаете над небольшим скриптом на Python или над целым проектом, выбор списка или какого-либо другого типа последовательности может быть не таким очевидным для вас.
Но выбор правильной структуры для ваших данных очень важен!
Списки против кортежей
Кортежи используются для хранения неизменяемых упорядоченных наборов элементов. Это означает следующее:
- вы не можете добавлять элементы в кортеж. Таким образом, методов append() или extend() для кортежей не существует;
- вы не можете удалять элементы из кортежа. Значит, методов remove() и pop() также нет;
- но вы можете находить элементы в кортеже, так как это его не изменяет;
- также вы можете использовать оператор in для проверки нахождения элемента в кортеже.
Таким образом, если у вас есть постоянное множество значений и вы не собираетесь ничего с ним делать (кроме перебора), то используйте кортежи вместо списков. Их использование будет быстрей и безопасней, так как они защищены от записи.
Списки против словарей
- список хранит упорядоченную последовательность элементов, то есть ее порядок поддерживается. Словари не поддерживают порядок данных.
- словари связывают каждый ключ со значением, а списки содержат только значения.
Используйте словарь, когда у вас есть неупорядоченный набор уникальных ключей, которые сопоставляются с определенными значениями.
Заметим, что при проверке на наличие элемента производительность словарей будет выше.
Списки против множеств
- Как и словари, множества это неупорядоченные наборы данных (в отличие от списков).
- Множества требуют, чтобы данные, хранящиеся в них, были хэшируемыми. Списки поддерживают хранение нехэшируемых типов данных.
- Множества требуют, чтобы элементы, содержащиеся в них, были уникальными и неизменяемыми. Дубликаты недопустимы во множествах, в то время как в списках они возможны, равно как и возможно и изменять сами элементы.
Вы можете использовать множества, когда у вас есть неупорядоченный набор уникальных неизменяемых значений, которые также можно хэшировать.
Вы не уверены, какие значения можно хэшировать?
Взгляните на таблицу ниже:
| Хэшируемые объекты | нехэшируемые объекты |
|---|---|
| Floats | Dictionaries |
| Integers | Sets |
| Tuples | Lists |
| Strings | |
| frozenset() |
Не верьте нам на слово! Поэксперементируйте сами!
Обратите внимание, что поскольку вы работаете с хэшируемыми элементами, проверка того, является ли определенный элемент частью вашей последовательности, будет проходить быстрее со множествами, чем со списками.
2. Как лучше выбирать элементы из списка?
Если вы хотите продуктивно работать со списками, то должны уметь получать доступ к данным, хранящимся в них.
Обычно мы получаем доступ к элементам списков, чтобы изменять определенные значения, обновлять или удалять их, или выполнять какие-либо другие операции с ними. Мы получаем доступ к элементам списков и, собственно, ко всем другим типам последовательностей, при помощи оператора индекса [] . Внутри него мы помещаем целое число.
Запустите данный код и убедитесь, что вы получите первый элемент списка, сохраненного в переменную biggerZoo . Это может быть поначалу несколько непривычно, но нумерация начинается с числа 0 , а не 1 .
Как получить последний элемент списка?
Ответ на этот вопрос является дополнением к объяснению в предыдущем разделе.
Попробуйте ввести отрицательное значение, например, -1 или -2 , в оператор индекса, чтобы получить последние элементы нашего списка biggerZoo !
Не правда ли, не слишком сложно?
Что означает ошибка «Index Out Of Range»?
Эта ошибка одна из тех, которые вы будете видеть достаточно часто, особенно если вы новичок в программировании.
Лучший способ понять эту ошибку — попробовать ее получить самостоятельно.
Возьмите ваш список и передайте в оператор индекса либо очень маленькое отрицательное число, либо очень большое положительное число.
Как видите, вы можете получить ошибку «Индекс вне диапазона» в случаях, когда вы передаете в оператор индекса целочисленное значение, не попадающее в диапазон значений индекса списка. Это означает, что вы присваиваете значение или ссылаетесь на (пока) несуществующий индекс.
Срезы в списках
Если вы новичок в программировании и в Python, этот вопрос может показаться одним из наиболее запутанных.
Обычно нотация срезов используется, когда мы хотим выбрать более одного элемента списка одновременно. Как и при выборе одного элемента из списка, мы используем двойные скобки. Отличие же состоит в том, что теперь мы еще используем внутри скобок двоеточие. Это выглядит следующим образом:
Вы можете видеть, что в первом случае мы выводим на экран список biggerZoo начиная с его элемента panda , который имеет индекс 2 . Иными словами, мы начинаем с индекса 2 и идем до конца списка, так как другой индекс не указан.
Что же происходит во втором случае, когда мы поменяли местами индекс 2 и двоеточие? Вы можете видеть, что мы получаем список из двух элементов, bear и lion . В данном случае мы стартуем с индекса 0 и доходим до индекса 2 (не включая его). Как вы можете видеть, результат не будет включать элемент panda .
В общем, подводя итоги:
Совет: передавая в оператор индекса только двоеточие, мы создаем копию списка.
В дополнение к простой нотации срезов, мы еще можем задать значение шага, с которым будут выбираться значения. В обобщенном виде нотация будет иметь следующий вид:
Так что же по сути дает значение шага?
Ну, это позволяет вам буквально шагать по списку и выбирать только те элементы, которые включает в себя значение вашего шага. Вот пример:
Обратите внимание, что если вы не указали какое-либо значение шага, оно будет просто установлено в значение 1 . При проходе по списку ни один элемент пропущен не будет.
Также всегда помните, что ваш результат не включает индекс конечного значения, который вы указали в записи среза!
Как случайным образом выбрать элемент из списка?
Для этого мы используем пакет random .
Если мы хотим выбрать случайный элемент из списка по индексу, то можем использовать метод randrange из той же библиотеки random .
Совет: обратите внимание на библиотеку random , она может вам пригодиться во многих случаях при программировании на Python.
3. Как преобразовать список в другие структуры данных в Python?
Иногда список это не совсем то, что вам надо. В этих случаях неплохо знать, как преобразовать свой список в более подходящую структуру данных. Ниже мы разберем несколько наиболее распространенных вариантов преобразования списков.
Как преобразовать список в строку
Преобразовать список в строку можно при помощи функции ».join() . Данная операция склеит все элементы нашего списка вместе и вернет строку. Более подробно об этом можно прочитать в документации.
Обратите внимание, что если ваш список содержит численные значения, то вы должны преобразовать их в строковые значения перед выполнением функции join . Это показано во втором примере нашего кода.
Для преобразования целого числа в строковое значение мы проходим циклом for по всему массиву чисел.
Как преобразовать список в кортеж
Преобразовать список в кортеж можно при помощи функции tuple() . Передайте в нее в качестве аргумента ваш список, и на выходе вы получите кортеж.
Помните, что кортежи это неизменяемый тип данных. После преобразования списка в кортеж в нем больше нельзя будет что-либо менять.
Как преобразовать список в множество
Как вы помните, множество — это неупорядоченная коллекция уникальных элементов. Таким образом, при преобразовании списка в множество будут потеряны не только возможные дубликаты в списке, но и порядок элементов.
Преобразовать список в множество можно при помощи функции set() . Просто передайте в нее ваш список, и на выходе получите множество.
Как преобразовать список в словарь
Словари в Python имеют дело с ключами и значениями, поэтому преобразование списка в словарь выглядит не таким явным. Допустим, у нас есть следующий список:
Нам нужно, чтобы пары элементов ‘hello’ и ‘world’ , а также ‘1’ и ‘2’ интерпретировались как пары ключ-значение. Чтобы это сделать, разобьем наш список на два одинаковых списка при помощи срезов и передадим эти два списка в функцию zip() .
В результате получим:
Заметьте, что для вывода результата на экран мы обернули функцию zip() в функцию list() .
Теперь передадим функцию zip() в функцию dict() , которая будет воспринимать элемент hello как ключ, а элемент world как значение. Сходным образом, 1 будет интерпретирован как ключ, а 2 — как значение.
В результате получится следующий словарь:
Если у вас список большой, то вероятно лучше будет сделать следующим образом:
Результат:
Заметим, что из итерируемого объекта всегда можно получить итератор. Объект итератор, в котором реализован метод __next__ , содержит в себе информацию о том, на каком шаге сейчас проходит итерация и каким будет следующий элемент последовательности.
4. В чем разница между методами append() и extend()?
Давайте возьмемся за этот вопрос, вернувшись к концепции итерируемости, которую мы объяснили в начале нашей статьи.
Не забывайте, что мы называем переменную итерируемой, если программа может производить итерации по ней. Иными словами, итерируемая переменная представляет из себя последовательность элементов. Как вы, вероятно, уже прочли в начале статьи, списки являются последовательностями, а все экземпляры последовательностей в Python являются итерируемыми.
Совет: чтобы проверить, является ли переменная итерируемой, воспользуйтесь методом __iter__. Вот пример такого кода:
Запустите данный код самостоятельно и убедитесь, что списки являются итерируемыми объектами.
Теперь, держа в уме концепцию итерируемости, начнем постигать разницу между этими двумя методами. Метод extend() , с одной стороны, принимает итерируемую переменную (скажем, список, кортеж или множество) и по одному добавляет к исходному списку элементы этой итерируемой последовательности.
Метод append() , с другой стороны, просто добавляет свой аргумент к концу исходного списка как единичный элемент. То есть, принимая в качестве аргумента итерируемую переменную, метод append() обрабатывает ее как единичный объект.
На примере следующего кода очень легко увидеть и понять разницу в работе этих методов:
Результат:
5. Как в Python работают представления списков?
Представление списков это, в сущности, просто элегантный способ конструирования списков в Python. Особенно этот способ понравится тем, кто любит математику. Судите сами:
Результат:
Итак, что же произошло? Мы взяли все целые числа от 0 до 10 (исключая 10) и каждое число возвели в квадрат.
Согласитесь, не очень сложно. Теперь давайте поднимем планку.
Давайте получим такой же список, но будем брать только четные числа, то есть те, которые нацело делятся на 2 . Это также очень просто сделать при помощи представления списков.
Результат:
Мы просто добавили при помощи инструкции if условие в наше первоначальное выражение. Если это условие выполняется, то число возводится в квадрат и добавляется в результирующий список, а если нет, то пропускается. В нашем случае это условие делимости на 2 без остатка.
Итак, в более общем смысле, вы также можете использовать представление списков для преобразования ваших списков в другие списки, что звучит немного сложнее, не так ли?
Рассмотрим следующий пример:
Результат:
В данном примере у нас уже есть список myList , который мы преобразуем при помощи представления списков. Вы опять можете видеть, что выражение for x in myList обеспечивает выполнение некоторых операций для всех элементов списка myList .
Теперь обратите внимание на выражение (lambda x: x*x) . Для простоты, вы должны просто знать, что лямбда-функции — это анонимные функции, которые создаются во время выполнения. Учитывая это, вы можете просто сосредоточиться на выражении х * х .
Отсюда видно, что эта функция просто принимает один элемент и умножает его на самого себя, то есть возводит в квадрат. Это анонимная функция, поэтому вам нужно передать ей свой элемент списка, чтобы убедиться, что лямбда-функция принимает его в качестве входных данных. Поэтому мы видим такое выражение: (lambda x: x*x)(x) .
Для лучшего понимания вторую строку кода можно переписать следующим образом:
Здесь мы просто определяем лямбда-функцию заранее.
Стоит отметить, что помимо представления списков существуют также представления словарей и представления множеств.
6. Как разбить список Python на равные части?
Чтобы разбить список на равные части, можно воспользоваться функцией zip() в сочетании с функцией iter() .
Результат:
Данный код работает следующим образом:
- Функция iter() создает итератор последовательности.
- Выражение [iter(x)] * 3 создает три объекта типа listiterator , каждый из них — итератор списка x .
- Символ « * «, стоящий перед аргументом в функции zip() , распаковывает стоящее после него выражение таким образом, как будто мы передаем один и тот же итератор в функцию три раза, и из каждого итератора функция извлекает элемент.
Стоп! Последний шаг абсолютно непонятен!
Давайте еще раз пройдемся по шагам:
- У нас есть три объекта итератора списка x. Представим их следующим образом:
[1,2,3,4,5,6,7,8,9], [1,2,3,4,5,6,7,8,9], [1,2,3,4,5,6,7,8,9] - В первый раз функция zip() берет по одному элементу последовательно из итераторов списка, что дает нам следующую картину:
[1][2][3]
Обратите внимание, что объекты итератора внимательно отслеживают, какой элемент идет следующим! - Во второй раз следующие элементы будут добавлены в три наши списка, что соответственно даст нам:
[1, 4], [2, 5], [3, 6] - И в последний раз, после выполнения данной процедуры мы получим:
[1, 4, 7], [2, 5, 8], [3, 6, 9] - Соединение этих списков вместе даст нам следующий список из трех кортежей:
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]
Если вы хотите применить эту логику в самостоятельно написанной функции, то можете получить вот такой результат:
Результат:
Функция chunks() принимает в качестве аргументов список и число частей, на которые его надо разделить.
Внутри нее вы видите цикл, диапазон которого задается функцией range(0, len(list), chunkSize) . Он начинается от 0 и заканчивается целым числом, обозначающим длину списка. Величина шага задается числом chanksize , которое является аргументом функции chank() .
Для каждого элемента в этом списке, построенном с помощью функции range () , вы получаете фрагмент исходного списка, начиная с индекса элемента и заканчивая индексом + размером блока, который задан в переменной chanksize .
Заметим, что для более красивой печати мы используем функцию pprint () , что расшифровывается как pretty print.
Вместо написания функции мы также можем использовать представление списков:
Результат:
7. Как производить математические вычисления при помощи списков Python
Зачастую мы используем списки только для хранения в них информации, но мы также можем и производить с их помощью математические вычисления. В данном разделе мы постараемся ответить на наиболее распространенные вопросы на эту тему.
Как вычислить средневзвешенное значение списка
Средневзвешенное значение весьма похоже на среднее значение, но все же не совсем. Средневзвешенное значение зависит не только от значений переменных, но и от их весов.
Данное определение может показаться несколько туманным, поэтому его лучше разобрать на конкретном примере. Допустим, у нас есть два списка.
Тогда мы при помощи следующего кода можем легко вычислить средневзвешенное значение:
Результат:
Но есть и другие способы это сделать. Например, следующий:
Или вот такой вариант:
И наконец, мы можем вычислить средневзвешенное значение с помощью функции zip() .
Для этого мы сначала создадим переменную costAndCases , в которую сохраним результат выполнения функции zip(), аргументами которой будут списки cost и case . В результате мы увидим список, состоящий только из кортежей. Первое значение каждого из кортежей будет из списка cost , что соответствует цене, а второе — из списка case , что обозначает количество покупок по данной цене.
Не забыли, что функция zip() делает с вашими списками? Она буквально поэлементно связывает их вместе в один список, состоящий из кортежей. Например, выражение zip(cost, cases) даст следующий результат:
Как посчитать квантиль
Квантили, наряду с максимумами и минимумами, используются для составления сводного анализа данных. Также выделяют 25%, 50% и 75% квантили (процентили), их еще называют 1, 2 и 3 квартиль соответственно.
Таким образом, вам необходимо вычислить минимум пять чисел, чтобы составить краткую справку по вашим данным. А именно: минимум, максимум, медиана и два квартиля.
Минимум и максимум найти несложно, но что насчет квартилей?
Это также просто. Допустим, у нас есть набор данных, состоящий из 25 наблюдений, отсортированный от минимума к максимуму.
- 25% процентиль или, иначе говоря, первый квартиль, вычисляется посредством умножения 0.25 на 25 . В результате получаем 6.25 , при округлении в большую сторону 7 . Это дает нам номер нашего наблюдения, который и будет искомым квартилем.
- Тритий квартиль, он же 75% процентиль мы вычисляем, умножая 0.75 на 25 . В результате получаем 18.75 , что при округлении дает 19 . Таким образом, мы получаем 19 элемент нашего списка, который и будет искомой величиной.
- Медианное значение вычисляется при помощи умножения 0.5 на 25 . После округления им будет 13 элемент нашего списка.
Но как это оформить в виде программы?
Самый простой способ — использовать NumPy. Вот пример вычисления медианного значения (он же 50% процентиль или второй квартиль):
Результат:
Как поэлементно суммировать списки
Допустим, у нас есть два списка:
И мы хотим получить в результате список, состоящий из сумм соответствующих элементов этих списков. Есть несколько способов это сделать.
При помощи базового Python
В результате получаем следующий список: [5, 7, 9] .
Или мы можем использовать представление списков вместе с функцией zip() .
При помощи NumPy
Предыдущие примеры отлично работают с небольшими списками, но когда вы работаете с большими данными, лучше использовать NumPy.
Вам нужно будет импортировать библиотеку NumPy и конвертировать ваши списки в массивы NumPy.

Английский для программистов
Наш телеграм канал с тестами по английскому языку для программистов. Английский это часть карьеры программиста. Поэтому полезно заняться им уже сейчас
Функция slice() — срез списка в Python
Чтобы нарезать список в Python, используйте встроенную функцию slice().
Эта функция возвращает объект среза и мы можем использовать его, чтобы нарезать список в Python. Все, что нам нужно сделать, это передать объект среза в виде индекса в квадратных скобках после переменной списка. Это выражение возвращает нарезанный список.
Ниже приведен пример фрагмента кода для фрагментации списка с определенным значением для параметра остановки в функции фрагмента.
Ниже приведен пример фрагмента кода для нарезки списка с определенным значением для запуска, остановки и необязательным параметром шага в функции фрагмента.
Пример 1: с определенной конечной позицией
В этом примере мы подготовим объект-слайс с определенной конечной позицией stop = 5 и будем использовать этот объект-слайс для разрезания данного списка.
Объект среза будет содержать индексы [0, 1, 2, 3] для данного стоп-значения 4. И элементы в списке, соответствующие этим индексам, – [‘a’, ‘b’, ‘c’, ‘d’ ]. Следовательно, результирующий список будет [‘a’, ‘b’, ‘c’, ‘d’].
Пример 2: с определенными начальной и конечной позициями
В этом примере мы подготовим объект-слайс с определенными положениями начала и конца и будем использовать этот объект-слайс для разрезания данного списка.
Объект среза будет содержать индексы [2, 3, 4, 5, 6] для заданных начальных и конечных значений. И элементы в списке, соответствующие этим индексам, должны быть возвращены list_1 [slice_object]. Следовательно, результирующий список [‘c’, ‘d’, ‘e’, ‘f’, ‘g’].
Пример 3: с определенными начальными и конечными положениями, шагом
В этом примере мы подготовим объект среза с определенными положениями начала и конца, а также определенным значением для шага. Затем мы будем использовать этот объект для нарезки данного списка.
Объект среза будет содержать индексы [2, 4, 6]. И элементы в списке, соответствующие этим индексам, должны быть возвращены list_1 [slice_object]. Следовательно, итоговый список [‘c’, ‘e’, ‘g’].
Заключение
В этом руководстве примеров в Python мы узнали, как разрезать список, используя встроенную функцию slice().