Базовый срез
Для любого итерируемого объекта (например, строки, списка и т. Д.) Python позволяет срезать и вернуть подстроку или подсписок своих данных.
Формат для среза:
iterable_name[start:stop:step]
где,
start
первый индекс среза. По умолчанию 0 (индекс первого элемента)stop
последний индекс среза. По умолчанию len (индекс последнего элемента)step
шаг размера среза.(лучше объясняется в примере ниже)
Примеры:
a = "abcdef"
a # так же как a[:] или a[::] если используются индексы по умолчанию всех трех индексов
>>>Out: 'abcdef'
a[-1]
>>>Out: 'f'
a[:]
>>>Out: 'abcdef'
a[::]
>>>Out: 'abcdef'
a[3:] # от элемента с индексом 3 до конца(размер шага имеет значение по умолчанию)
>>>Out: 'def'
a[:4] # от начала (по умолчанию 0) до позиции 4 (не включая ее)
>>>Out: 'abcd'
a[2:4] # от позиции 2 до позиции 4 (не включая ее)
>>>Out: 'cd'
Кроме того, любой из вышеперечисленных срезов может использоваться с определенным размером шага:
a[::2] # каждый второй элемент
>>>Out: 'ace'
a[1:4:2] # от индекса 1 до индекса 4 (исключая), каждый второй элемент)
>>>Out: 'bd'
Индексы могут быть отрицательными, и в этом случае они вычисляются с конца последовательности
a[:-1] #от нулевого индекса (по умолчанию) до 2ого индекса с конца (последний элемент - 1)
>>>Out: 'abcde'
a[:-2] # от нулевого индекса (по умолчанию) до 3его индекса с конца (последний элемент - 2)
>>>Out: 'abcd'
a[-1:] # от последнего элемента до конца (по умолчанию len())
>>>Out: 'f'
Размер шага также может быть отрицательным, в этом случае срез будет перебирать список в обратном порядке:
a[3:1:-1] # от индекса 2 до None (по умолчанию), в обратном порядке)
>>>Out: 'dc'
Эта конструкция полезна для обращения итеративного
a[::-1] # от последнего элемента (по умолчанию len()-1), до первого в обратном порядке (-1))
>>>Out: 'fedcba'
Обратите внимание на то, что для отрицательных шагов по умолчанию end_index
не None
a[5:None:-1] # эквивалентно a[::-1]
>>>Out: 'fedcba'
a[5:0:-1] # от последнего элемента (индекс 5) до второго элемента (индекс 1)
>>>Out: 'fedcb'
Создание мелкой копии массива
Быстрый способ сделать копию массива (в отличие от присвоения переменной с другой ссылкой на исходный массив):
arr[:]
Давайте рассмотрим синтаксис. [:]
Означает , что start
, end
, и slice
все опущены. Они по умолчанию равны 0
, len(arr)
, и 1
, соответственно, что означает, что мы запрашиваем не будет иметь все элементы arr
от начала до самого конца. На практике это выглядит примерно так:
arr = ['a', 'b', 'c']
copy = arr[:]
arr.append('d')
print(arr)
>>>Out: ['a', 'b', 'c', 'd']
print(copy)
>>>Out: ['a', 'b', 'c']
Как вы можете видеть, arr.append('d')
добавил d
к arr
, но copy
осталась неизменной!
Обратите внимание, что это делает неполную копию, и copy
не идентичен arr.copy()
.
Разворот объекта
Вы можете использовать срезы для легкого разворота str
, list
или tuple
(или в основном любой набор объектов , который реализует срез с параметром шага). Вот пример разворота строки, хотя это в равной степени относится и к другим типам, перечисленным выше:
s = 'reverse me!'
s[::-1]
>>>Out: '!em esrever'
Давайте быстро посмотрим на синтаксис. [::-1]
означает , что срез должен быть с самого начала до конца строки (потому что start
и end
опущены) и шаг -1
означает , что он должен двигаться через колонну в обратном направлении.
Индексирование пользовательских классов: __getitem__, __setitem__ и __delitem__
class MultiIndexingList:
def __init__(self, value):
self.value = value
def __repr__(self):
return repr(self.value)
def __getitem__(self, item):
if isinstance(item, (int, slice)):
return self.__class__(self.value[item])
return [self.value[i] for i in item]
def __setitem__(self, item, value):
if isinstance(item, int):
self.value[item] = value
elif isinstance(item, slice):
raise ValueError('Невозможно интерпретировать срез с множественным индексированием')
else:
for i in item:
if isinstance(i, slice):
raise ValueError('Невозможно интерпретировать срез с множественным индексированием')
self.value[i] = value
def __delitem__(self, item):
if isinstance(item, int):
del self.value[item]
elif isinstance(item, slice):
del self.value[item]
else:
if any(isinstance(elem, slice) for elem in item):
raise ValueError('Невозможно интерпретировать срез с множественным индексированием')
item = sorted(item, reverse=True)
for elem in item:
del self.value[elem]
Это позволяет нарезать и индексировать для доступа к элементу:
a = MultiIndexingList([1,2,3,4,5,6,7,8])
a
>>>Out: [1, 2, 3, 4, 5, 6, 7, 8]
a[1,5,2,6,1]
>>>Out: [2, 6, 3, 7, 2]
a[4, 1, 5:, 2, ::2]
>>>Out: [5, 2, [6, 7, 8], 3, [1, 3, 5, 7]]
# 4|1-|----5:---|2-|-----::2----- <-- определяет какой элемент пришел из какой позиции
Во время установки и удаления элементов допускает только запятые целочисленной индексации (без нарезки):
a[4] = 1000
a
>>>Out: [1, 2, 3, 4, 1000, 6, 7, 8]
a[2,6,1] = 100
>>>Out: [1, 100, 100, 4, 1000, 6, 100, 8]
del a[5]
a
>>>Out: [1, 100, 100, 4, 1000, 100, 8]
del a[4,2,5]
a
>>>Out: [1, 100, 4, 8]
Назначение среза
Еще одна полезная функция, использующая срезы- это назначение срезов. Python позволяет назначать новые фрагменты для замены старых фрагментов списка за одну операцию.
Это означает, что если у вас есть список, вы можете заменить несколько членов в одном назначении:
lst = [1, 2, 3]
lst[1:3] = [4, 5]
print(lst)
>>>Out: [1, 4, 5]
Назначение также не должно совпадать по размеру, поэтому, если вы хотите заменить старый срез новым, отличающимся по размеру, вы можете:
lst = [1, 2, 3, 4, 5]
lst[1:4] = [6]
print(lst)
>>>Out: [1, 6, 5]
Также возможно использовать известный синтаксис среза для таких вещей, как замена всего списка:
lst = [1, 2, 3]
lst[:] = [4, 5, 6]
print(lst)
>>>Out: [4, 5, 6]
Или только два последних члена:
lst = [1, 2, 3]
lst[-2:] = [4, 5, 6]
print(lst)
>>>Out: [1, 4, 5, 6]
Базовое индексирование
В списках Python первый элемент в списке можно получить по индексу 0
arr = ['a', 'b', 'c', 'd']
print(arr[0])
>>>Out: 'a'
Вы можете получить доступ к второму элементу в списке по индексу 1
, третий элемент по индексу 2
и так далее:
print(arr[1])
>>>Out: 'b'
print(arr[2])
>>>Out: 'c'
Вы также можете использовать отрицательные индексы для доступа к элементам в конце списка. например. индекс -1
даст вам последний элемент списка и индекс -2
даст вам второй до последнего элемента списка:
print(arr[-1])
>>>Out: 'd'
print(arr[-2])
>>>Out: 'c'
Если вы пытаетесь получить доступ к индексу , которого нет в списке, будет вызвана ошибка IndexError
:
print arr[6]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range