Вступление
К вашему вниманию гайд по слайсингу (AKA суши-оператор, слайс, срез)! Наверно, все пишущие на питоне знают о синтаксисе вырезания частей последовательности - s[a:b]
. Сейчас же мы рассмотрим как самые очевидные, так и менее известные факты об операции получения среза.
(Но прежде чем начнём, нужно уточнить, что в Python как и во многих других языках последний элемент не включается в срезы и диапазоны, что соответствует индексации с нуля. seq[начало:конец:шаг]
(Для вычисления данного выражения Python вызывает seq.__getitem__
) - берёт срез от НАЧАЛО, до КОНЕЦ (не включая его), с шагом ШАГ. По умолчанию НАЧАЛО = 0, КОНЕЦ = длине объекта, ШАГ = 1. Соответственно, какие-нибудь, а возможно и все (seq[:], поговорим об этом позже
) параметры могут быть опущены).
Получение по срезу
"Python" | |||||
P |
Y |
T |
H |
O |
N |
0 |
1 |
2 |
3 |
4 |
5 |
-6 |
-5 |
-4 |
-3 |
-2 |
-1 |
>>> some_str = "Python"
>>> some_str[:1] # Задаём конечным индексом 1, а т.к. конец не включается, мы получим первый элемент последовательности ('P').
'P'
>>> PYTH = slice(0, 4) # Вместо того чтоб загромождать код вшитыми диапазонами, мы можем проименовать их (например для упрощения разбора накладной).
>>> some_str[PYTH]
'Pyth'
>>> some_str[::2] # Шагаем через букву.
'Pto'
Немного о NumPy
Оператор [] может принимать несколько индексов или срезов, разделённых запятыми a[m:n, k:l]
. В основном это используется в NumPy для получения двумерного среза и a[i, j]
для получения одного элемента двумерного массива. Соответственно для вычисления a[i, j]
Python вызывает a.__getitem__((i, j))
. Кстати, т.к. "..."
(единственный экземпляр класса ellipsis) распознаётся как лексема, то мы его можем использовать так же и в срезах. Применение этому нашлось в том же NumPy для сокращённого создания среза двумерного массива. Детальнее - https://scipy.github.io/old-wiki/pages/Tentative_NumPy_Tutorial.
Удаление по срезу
Так же мы можем удалять элементы последовательности по срезу с учётом того, что она поддерживает удаление элементов (изменяема))). Приведу пример с рантайм классом SupportsDeletion
.
>>> import typing
>>> @typing.runtime_checkable
>>> class SupportsDeletion(typing.Protocol):
>>> def __delitem__(self, key: typing.Any) -> typing.Any:
>>> ...
>>> for builtin_type in (list, dict, str, tuple):
>>> print(builtin_type.__name__, "->", isinstance(builtin_type, SupportsDeletion))
list -> True
dict -> True
str -> False
tuple -> False
>>> seq = [1, 2, 3, 4]
>>> del seq[:3] # Удаляем первых три элемента последовательности.
>>> seq
[4]
Лайфхаки :)
№1 Можно перевернуть последовательность, если запросить срез seq[::-1]
>>> seq = (1, 2, 3, 4, 5, 6)
>>> seq[::-1]
(6, 5, 4, 3, 2, 1)
№2 Как удалить все элементы списка с помощью слайса, не разрушая сам обьект-список? (Разумеется, тот же результат можно получить вызвав метод .clear()
у списка, но мы же сейчас про слайсы говорим + его нет во второй версии питона).
>>> seq = [1, 2, 3, 4, 5, 6]
>>> id(seq)
2071031395200
>>> del seq[:]
>>> id(seq)
2071031395200
>>> seq
[]
№3 Помимо очистки списков, нарезку также можно использовать для замены всех элементов списка, не создавая новый объект-список. Это отличная сокращённая запись для очистки списка и затем повторного его заполнения вручную:
>>> seq = [1, 2, 3, 4, 5, 6, 7]
>>> original_list = seq
>>> seq[:] = [1, 2, 3]
>>> seq
[1, 2, 3]
>>> original_list
[1, 2, 3]
>>> original_list is seq
True
Приведённый выше пример кода заменил все элементы в seq
, но не уничтожил и воссоздал список как таковой. По этой причине старые ссылки на оригинальный объект-список по-прежнему действительны.
№4 Создание мелких копий существующих списков:
>>> seq = [1, 2, 3, 4, 5, 6, 7]
>>> copied_list = seq[:]
>>> copied_list
[1, 2, 3, 4, 5, 6, 7]
>>> copied_list is seq
False
Создание мелкой копии означает, что копируется только структура элементов, но не сами элементы. Обе копии списка совместно используют одинаковые экземпляры отдельных элементов.
Если же вам необходимо продублировать абсолютно всё, включая и элементы, то необходимо создать глубокую копию списка (copy.deepcopy(x)
). Для этой цели пригодится встроенный модуль в Python copy.
Ключевые выводы
Слайсы полезны не только для отбора элементов внутри последовательности, а могут также использоваться для очистки, реверсирования и копирования списков.
Комментарии (14)
uchitel
04.11.2021 08:34Если текст для новичков, то руководствоваться надо принципом "Примеры обучают лучше чем теория". Если текст для тех кто занимается самообразованием, то руководствоваться надо принципом "Лучше иметь и не нуждаться, чем нуждаться и не иметь" т.е. пусть лучше материал будет избыточен. Если это публичное самообразование, то лучше не дублировать то, что можно и так без труда нагуглить ("без труда" это все, что выше 30-40-й строчки поисковой выдачи), а взять какую-то действительно сложную тему.
Глубину статьи оценить очень легко - она ниже Саммерфилда, ниже Лутца, ниже Доусона, ниже некоторых сайтов о Python. То же самое касается и NumPy (хотя бы упомянуть про r_, c_, s_ не мешало), где было бы по настоящему круто - углубиться в тему индексации.
У вас просто не получится писать на Хабре такие статьи на постоянной основе, на Дзене получится.
Kadabrov
04.11.2021 09:40Здравствуйте, я пользователь данного ресурса, изучил статью и не вижу повода, чтобы ее минусовать, опять же исходя из количества закладок это полезный материал.
Где можно изучить критерии глубины и годности статей, чтобы принимать это за стандарт и понимать где плюсовать статье или минусовать, конечно если это не субъективные показатели?
gnomeby
04.11.2021 16:40Конечно это субъективные показатели, но они вполне нормально нащупываются въедливым чтением хабра долгое время (жопное чувство).
Самая большая ошибка автора статьи - отплёвывание от саркастических комментариев на очень серьёзных щах. Тут такое не любят. Без этого вполне бы зашло за проходную непопулярную статью.
Animatea Автор
04.11.2021 09:55-7Не ожидал, что моя статья вызовет такой резонанс)). Я очень благодарен тем, кто написал в поддержку. Вы абсолютно правы: доброжелательность на сайте однозначно будет способствовать развитию умения писать статьи у всех, кто тут присутствует. А тем, кто решил выпендриваться на фоне - тоже спасибо и информация на будущее: у любого специалиста в каком-либо вопросе всегда есть и результаты вау, и результаты попроще. Только тот, кто ничего не делает может всегда считать себя в топе))). Так что не спешите вешать ярлыки, определяя кому и куда надо) Ваше мнение не должно и не будет влиять на выбор интересующей Меня темы. Так что если в следующий раз вам что-то не понравится - идите дальше.... Куда шли) Попутного ветра) Любая информация ВСЕГДА найдет своего читателя. Видимо, эта Не для вас))
Всем добра ))
hottabxp
У вас опечатка в адресе сайта. У вас "habr.com", а должно быть "zen.yandex.ru". Исправьте пожалуйста.
Animatea Автор
В первую очередь хочется поблагодарить Вас за столь интересно изложенный отзыв о нашей статье. Грустно, что в этот раз у нас не получилось приложить все усилия, чтобы донести до вас столь сложную в освоении информацию. Мы обязательно учтём все ваши пожелания и будем стремиться к лучшему!
P.S. Я рекомендую Вам вашу единственную статью отправить туда же, её место определённо там. Хорошего Вам вечера.
herrjemand
Вы уж простите, но ваша статья еле тянет на StackOverflow ответ и автор оригинального комментария абсолютно прав. Я бы для начала сел и подумал что вы хотите донести и кому. Если вы считаете что ваша аудитория Хабр, то не обижайтесь когда ваш поверхностный материал даже не хотят изложено критиковать. Тут объективно нечего критиковать.
Данный текст отлично пойдет на Zen. На хабре стандарты немного выше.
У вас есть инвайт, воспользуйтесь им и напишите глубокую, годную статью. Получите лайки и будете тешиться. Обижаться на настолько безобидный сарказм это ну уж как-то вообще.
Animatea Автор
Я ответил на глупый комментарий, а не обижался, это во-первых)) во-вторых, по каким критериям вы оцениваете "глубину" статьи? По вашему глубокому восприятию?)) Не забывайте, пожалуйста, о том, что ваш комментарий такой же субъектианый, как и предыдущего субъекта). Безусловно, контент не может заходить всем, кому-то нравится, кому-то - нет. Вы тут такой же пользователь как и я. На каком основании вы позволяете себе определять что достойно, а что нет?) Лично я считаю эту статью интересной, и на сейчас даже не только я. Так что оставьте своё Субъективное мнение при себе) В вашу компетенцию не входит раздача рекомендаций))
P.s. Акцентирую: я не обижаюсь на вас, я не понимаю почему вы решили измерить глубину моего текста)). Здесь каждый может выражать то,что считает важным и интересным. Рекомендация вам на будущее: постарайтесь в следующий раз повышать свою важность и самооценку другими способами и не за счёт других) хорошего вечера)
vodopad
Шутки шутками, но автора статьи загнобили слишком сильно. Безусловно, качество и ценность материала не такая высокая, однако для кого-то это действительно может быть полезным. Или интересным. Для студентов, для тех, кто не является разработчиком, но редко программирует на Python.
Из-за таких комментариев люди боятся писать статьи на Хабре. Мол загнобят, заминусуют, выставят дураком. Испортят настроение, понизят самооценку.
Хабр же должен быть рассчитан на всех, и на новичков, и на профессионалов. И если человек хочет написать статью, то пусть пишет. Вдруг он через 2-5 лет начнёт такие статьи писать, что прям вах. Повысит свой уровень. Научиться излагать свои мысли.
>На хабре стандарты немного выше.
С этим утверждением категорически не согласен. 80% публикуемого материала на Хабре -- мусор. Особенно из корпоративных блогов. Раньше тут было очень много статей для новичков. И все учились благодаря Хабру, делали первые шаги. Всем было хорошо. А сейчас технического материала не осталось. И первая причина, на мой взгляд, как раз в токсичности и в недружелюбии. Зачем портить своё время на написание статьи, а потом ещё читать оскорбления в комментариях...
unsignedchar
Присоединяюсь, пожалуй. Если уровень статьи не дотягивает до некоторой условной планки (где она, кстати?) - можно просто не читать. Зачем оскорбляться? Тем более что ничего антинаучного в ней нет ;)
lesskop
Браво, маэстро. Проникся комментарием. Тоже часто боюсь написать статью, потому что знаю, какие тут сидят токсики, и какой уровень материала им нужно подавать.
unsignedchar
Кто
покупательчитатель вашей статьи? Нужно включать своего внутренного маркетолога и с ним консультироваться. Рефераты уровня «лишь бы получить зачет» точно никому не интересны. Даже автору.Firsto