Перейти к содержимому
Editor

Срезы в Python: индексация строк, списков и кортежей

Начальный20 min6 упр.80 XP

Этот урок переведён с английского оригинала.Read in EnglishLeer en españolСообщить об ошибке в переводе

0/6 упр.

Представьте пиццу, разрезанную на 8 кусков с номерами от 0 до 7. Не всегда нужна вся пицца целиком. Иногда нужны куски со 2-го по 5-й. Иногда каждый второй кусок. А иногда три последних.

Срезы в Python позволяют взять часть любой последовательности (списка, строки или кортежа) с помощью одной и той же простой записи. Это одна из самых изящных возможностей Python, и, освоив её, вы будете пользоваться ею повсюду.

В этом уроке вы изучите запись start:stop:step, узнаете, как работают отрицательные индексы и как развернуть любую последовательность, а также познакомитесь с самыми распространёнными приёмами работы со срезами, которыми Python-разработчики пользуются каждый день.

Как работают простые срезы?

Базовый синтаксис среза выглядит так: sequence[start:stop]. Срез возвращает элементы начиная с индекса start и до индекса stop (но не включая его). Можно считать это полуоткрытым интервалом.

Простой срез с start:stop
fruits = ['apple', 'banana', 'cherry', 'date', 'elderberry']
# Get items at index 1, 2 (stops before 3)
print(fruits[1:3]) # ['banana', 'cherry']
# Get the first three items
print(fruits[0:3]) # ['apple', 'banana', 'cherry']
# Get items from index 2 to the end
print(fruits[2:5]) # ['cherry', 'date', 'elderberry']
Вывод
['banana', 'cherry']
['apple', 'banana', 'cherry']
['cherry', 'date', 'elderberry']

Правило «остановиться перед stop» поначалу может показаться странным. Но у него есть приятное преимущество: fruits[0:3] даёт ровно 3 элемента. Количество элементов в срезе всегда равно stop - start.

Срезы без start и stop
numbers = [10, 20, 30, 40, 50, 60]
# First three items (omit start)
print(numbers[:3]) # [10, 20, 30]
# Everything from index 3 onward (omit stop)
print(numbers[3:]) # [40, 50, 60]
# Copy the entire list (omit both)
copy = numbers[:]
print(copy) # [10, 20, 30, 40, 50, 60]
Вывод
[10, 20, 30]
[40, 50, 60]
[10, 20, 30, 40, 50, 60]

Что делает параметр step?

Полный синтаксис среза выглядит так: sequence[start:stop:step]. Шаг (step) определяет, сколько элементов пропускать между теми, которые вы берёте. Шаг 2 берёт каждый второй элемент. Шаг 3 берёт каждый третий.

Использование параметра step
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# Every other item
print(numbers[::2]) # [0, 2, 4, 6, 8]
# Every other item starting from index 1
print(numbers[1::2]) # [1, 3, 5, 7, 9]
# Every third item
print(numbers[::3]) # [0, 3, 6, 9]
# From index 1 to 7, every 2nd item
print(numbers[1:7:2]) # [1, 3, 5]
Вывод
[0, 2, 4, 6, 8]
[1, 3, 5, 7, 9]
[0, 3, 6, 9]
[1, 3, 5]

Если вы указываете шаг, по умолчанию start равен 0, а stop совпадает с концом последовательности. Указывать их нужно, только если вы хотите сузить диапазон.

Как работают отрицательные индексы в срезах?

Отрицательные индексы отсчитываются с конца последовательности. -1 обозначает последний элемент, -2 предпоследний и так далее. Отрицательные числа можно использовать в любой части среза: в start, stop или step.

Срезы с отрицательными индексами
letters = ['a', 'b', 'c', 'd', 'e', 'f']
# Last three items
print(letters[-3:]) # ['d', 'e', 'f']
# Everything except the last two
print(letters[:-2]) # ['a', 'b', 'c', 'd']
# From second-to-last to last
print(letters[-2:]) # ['e', 'f']
Вывод
['d', 'e', 'f']
['a', 'b', 'c', 'd']
['e', 'f']

Отрицательные индексы невероятно полезны, когда вам нужны элементы, отсчитанные от конца. Например, my_list[-3:] всегда даёт три последних элемента, какой бы длины ни был список.

Отрицательные индексы в срезах строк
word = 'Python'
# Remove first and last character
print(word[1:-1]) # ytho
# Last 4 characters
print(word[-4:]) # thon
# First 2 characters
print(word[:2]) # Py
Вывод
ytho
thon
Py

Как развернуть последовательность с помощью [::-1]

Отрицательный шаг заставляет Python идти в обратную сторону. Самый распространённый приём записывается как [::-1] и разворачивает всю последовательность. Ни start, ни stop, шаг -1: Python идёт от конца к началу.

Разворот с помощью [::-1]
# Reverse a list
numbers = [1, 2, 3, 4, 5]
print(numbers[::-1]) # [5, 4, 3, 2, 1]
# Reverse a string
word = 'hello'
print(word[::-1]) # olleh
# Reverse a tuple
coords = (10, 20, 30, 40)
print(coords[::-1]) # (40, 30, 20, 10)
Вывод
[5, 4, 3, 2, 1]
olleh
(40, 30, 20, 10)

Отрицательный шаг можно сочетать с start и stop, чтобы развернуть только часть последовательности. При отрицательном шаге start должен быть больше stop, ведь вы движетесь в обратную сторону.

Отрицательный шаг вместе с start и stop
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# Reverse items from index 7 down to index 2 (not including 2)
print(numbers[7:2:-1]) # [7, 6, 5, 4, 3]
# Every other item, reversed
print(numbers[::-2]) # [9, 7, 5, 3, 1]
Вывод
[7, 6, 5, 4, 3]
[9, 7, 5, 3, 1]

Срезы строк, списков и кортежей

Один и тот же синтаксис [start:stop:step] работает для всех типов последовательностей. Разница только в том, что вы получаете в результате: срез списка даёт список, срез строки даёт строку, а срез кортежа даёт кортеж.

Срез сохраняет тип
# Slicing a string -> string
name = 'Alexander'
print(name[0:4]) # Alex
print(type(name[0:4])) # <class 'str'>
# Slicing a list -> list
scores = [90, 85, 77, 92, 88]
print(scores[1:4]) # [85, 77, 92]
# Slicing a tuple -> tuple
point = (10, 20, 30, 40, 50)
print(point[::2]) # (10, 30, 50)
Вывод
Alex
<class 'str'>
[85, 77, 92]
(10, 30, 50)

Популярные приёмы со срезами, которые должен знать каждый Python-разработчик

Вот приёмы со срезами, которые вы будете встречать и использовать чаще всего. Считайте это своей шпаргалкой.

Шесть главных приёмов со срезами
data = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
# First N items
print(data[:3]) # ['a', 'b', 'c']
# Last N items
print(data[-3:]) # ['e', 'f', 'g']
# Remove first item
print(data[1:]) # ['b', 'c', 'd', 'e', 'f', 'g']
# Remove last item
print(data[:-1]) # ['a', 'b', 'c', 'd', 'e', 'f']
# Middle items (remove first and last)
print(data[1:-1]) # ['b', 'c', 'd', 'e', 'f']
# Reverse the whole thing
print(data[::-1]) # ['g', 'f', 'e', 'd', 'c', 'b', 'a']
Вывод
['a', 'b', 'c']
['e', 'f', 'g']
['b', 'c', 'd', 'e', 'f', 'g']
['a', 'b', 'c', 'd', 'e', 'f']
['b', 'c', 'd', 'e', 'f']
['g', 'f', 'e', 'd', 'c', 'b', 'a']

Срез можно поставить и в левую часть присваивания, чтобы заменить участок списка. Это называется присваиванием срезу.

Присваивание срезу (только для списков)
colors = ['red', 'green', 'blue', 'yellow', 'purple']
# Replace items at index 1 and 2
colors[1:3] = ['lime', 'sky']
print(colors) # ['red', 'lime', 'sky', 'yellow', 'purple']
# You can even replace with a different number of items
colors[1:3] = ['orange']
print(colors) # ['red', 'orange', 'yellow', 'purple']
Вывод
['red', 'lime', 'sky', 'yellow', 'purple']
['red', 'orange', 'yellow', 'purple']

Упражнения

Возьмите средние элементы
Напишите код

Дан список animals. С помощью среза выведите только три средних элемента: ['cat', 'dog', 'elephant'].

animals = ['ant', 'bear', 'cat', 'dog', 'elephant', 'fox', 'giraffe']
# Print the middle three items using slicing
Предскажите результат среза
Угадайте вывод

Что выведет этот код? Хорошо подумайте, как работают отрицательные индексы.

word = 'programming'
print(word[-4:])

Напишите этот код и запустите его, чтобы проверить свой прогноз.

# What does this print?
word = 'programming'
print(word[-4:])
Элементы с чётными индексами
Напишите код

Дан список letters. С помощью среза с шагом выведите только элементы с чётными индексами (0, 2, 4, 6). Должно получиться ['a', 'c', 'e', 'g'].

letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
# Print items at even indices using slicing
Разверните слово
Напишите код

С помощью среза разверните строку word и выведите результат. Должно получиться nohtyp.

word = 'python'
# Reverse the word using slicing and print it
Исправьте ошибку в срезе
Исправьте ошибку

Этот код пытается получить три последних элемента списка, но использует неправильный срез. Исправьте ошибку, чтобы программа вывела ['date', 'elderberry', 'fig'].

fruits = ['apple', 'banana', 'cherry', 'date', 'elderberry', 'fig']
# Bug: this doesn't get the last three items
last_three = fruits[3:0]
print(last_three)
Проверка на палиндром
Напишите код

Напишите функцию is_palindrome(text), которая возвращает True, если текст читается одинаково слева направо и справа налево, и False в противном случае. Разверните строку с помощью среза. Сначала приведите текст к нижнему регистру, чтобы проверка не зависела от регистра букв.

Проверьте функцию такими вызовами:

print(is_palindrome('racecar'))
print(is_palindrome('Python'))
print(is_palindrome('Madam'))
def is_palindrome(text):
# Convert to lowercase and check if it equals its reverse
pass
print(is_palindrome('racecar'))
print(is_palindrome('Python'))
print(is_palindrome('Madam'))

Похожие уроки

Урок был полезен?