В Python самая основная форма для нарезки следующая:
l[start:end]
, где l
- некоторая коллекция, start
- включающий индекс, а end
- исключительный.
In [1]: l = list(range(10))
In [2]: l[:5] # first five elements
Out[2]: [0, 1, 2, 3, 4]
In [3]: l[-5:] # last five elements
Out[3]: [5, 6, 7, 8, 9]
При нарезке с начала вы можете опустить нулевой индекс, а при срезании до конца вы можете опустить конечный индекс, поскольку он избыточен, поэтому не будьте многословны:
In [5]: l[:3] == l[0:3]
Out[5]: True
In [6]: l[7:] == l[7:len(l)]
Out[6]: True
Отрицательные целые числа полезны при выполнении смещений относительно конца коллекции:
In [7]: l[:-1] # include all elements but the last one
Out[7]: [0, 1, 2, 3, 4, 5, 6, 7, 8]
In [8]: l[-3:] # take the last 3 elements
Out[8]: [7, 8, 9]
Можно указывать индексы, выходящие за границы при нарезке, такие как:
In [9]: l[:20] # 20 is out of index bounds, l[20] will raise an IndexError exception
Out[9]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [11]: l[-20:] # -20 is out of index bounds, l[-20] will raise an IndexError exception
Out[11]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Имейте в виду, что результатом нарезки коллекции является совершенно новая коллекция. Кроме того, при использовании обозначения среза в назначениях длина назначения среза не обязательно должна быть одинаковой. Значения до и после назначенного среза будут сохранены, а коллекция будет уменьшаться или увеличиваться, чтобы содержать новые значения:
In [16]: l[2:6] = list('abc') # assigning less elements than the ones contained in the sliced collection l[2:6]
In [17]: l
Out[17]: [0, 1, 'a', 'b', 'c', 6, 7, 8, 9]
In [18]: l[2:5] = list('hello') # assigning more elements than the ones contained in the sliced collection l [2:5]
In [19]: l
Out[19]: [0, 1, 'h', 'e', 'l', 'l', 'o', 6, 7, 8, 9]
Если вы пропустите начальный и конечный индексы, вы создадите копию коллекции:
In [14]: l_copy = l[:]
In [15]: l == l_copy and l is not l_copy
Out[15]: True
Если начальный и конечный индексы опущены при выполнении операции присваивания, весь контент коллекции будет заменен копией того, на что есть ссылка:
In [20]: l[:] = list('hello...')
In [21]: l
Out[21]: ['h', 'e', 'l', 'l', 'o', '.', '.', '.']
Помимо базовой нарезки, также можно применять следующие обозначения:
l[start:end:step]
, где l
- это коллекция, start
- это инклюзивный индекс, end
- это эксклюзивный индекс, а step
- это шаг, который можно использовать, чтобы взять каждый элемент nth в l
.
In [22]: l = list(range(10))
In [23]: l[::2] # take the elements which indexes are even
Out[23]: [0, 2, 4, 6, 8]
In [24]: l[1::2] # take the elements which indexes are odd
Out[24]: [1, 3, 5, 7, 9]
Использование step
предоставляет полезную хитрость для обращения коллекции в Python:
In [25]: l[::-1]
Out[25]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Также можно использовать отрицательные целые числа для step
в качестве следующего примера:
In[28]: l[::-2]
Out[28]: [9, 7, 5, 3, 1]
Однако использование отрицательного значения для step
может привести к путанице. Более того, чтобы быть Pythonic, вы должны избегать использования start
, end
и step
в одном слайсе. В случае, если это требуется, попробуйте выполнить это в двух заданиях (одно для нарезки, а другое для продвижения).
In [29]: l = l[::2] # this step is for striding
In [30]: l
Out[30]: [0, 2, 4, 6, 8]
In [31]: l = l[1:-1] # this step is for slicing
In [32]: l
Out[32]: [2, 4, 6]