Вот как я преподаю срезы новичкам:
Понимание разницы между индексацией и нарезкой:
Wiki Python обладает этой удивительной картиной, которая четко отличает индексирование и нарезку.
[/g1]
Это список с 6 элементами в нем. Чтобы лучше понять нарезку, рассмотрите этот список как набор из шести ящиков, расположенных вместе. Каждый ящик имеет в нем алфавит.
Индексация - это дело с содержимым окна. Вы можете проверить содержимое любой коробки. Но вы не можете проверить содержимое нескольких ящиков одновременно. Вы даже можете заменить содержимое поля. Но вы не можете поместить 2 шара в 1 коробку или заменить 2 шара за раз.
In [122]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']
In [123]: alpha
Out[123]: ['a', 'b', 'c', 'd', 'e', 'f']
In [124]: alpha[0]
Out[124]: 'a'
In [127]: alpha[0] = 'A'
In [128]: alpha
Out[128]: ['A', 'b', 'c', 'd', 'e', 'f']
In [129]: alpha[0,1]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
in ()
----> 1 alpha[0,1]
TypeError: list indices must be integers, not tuple
Нарезка - это как дело с ящиками. Вы можете перенести первый ящик и поместить его на другой стол. Чтобы забрать коробку, все, что вам нужно знать, это позиция начала & amp; окончание окна.
Вы даже можете забрать первые 3 ящика или последние 2 коробки или все ящики между 1 и am; 4. Итак, вы можете выбрать любой набор ящиков, если знаете начало & amp; окончание. Эти позиции называются start & amp; стоп-позиции.
Интересно, что вы можете сразу заменить несколько ящиков.
In [130]: alpha[0:1]
Out[130]: ['A']
In [131]: alpha[0:1] = 'a'
In [132]: alpha
Out[132]: ['a', 'b', 'c', 'd', 'e', 'f']
In [133]: alpha[0:2] = ['A', 'B']
In [134]: alpha
Out[134]: ['A', 'B', 'c', 'd', 'e', 'f']
In [135]: alpha[2:2] = ['x', 'xx']
In [136]: alpha
Out[136]: ['A', 'B', 'x', 'xx', 'c', 'd', 'e', 'f']
Нарезка с шагом:
До сих пор вы выбрали ящики непрерывно. Но несколько раз вам нужно отбирать дискретно. Например, вы можете записывать каждую вторую коробку. Вы даже можете забрать каждую третью коробку с конца. Это значение называется размером шага. Это представляет собой разрыв между вашими последовательными пикапами. Размер шага должен быть положительным, если вы выбираете ящики от начала до конца и наоборот.
In [137]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']
In [142]: alpha[1:5:2]
Out[142]: ['b', 'd']
In [143]: alpha[-1:-5:-2]
Out[143]: ['f', 'd']
In [144]: alpha[1:5:-2]
Out[144]: []
In [145]: alpha[-1:-5:2]
Out[145]: []
Как Python показывает отсутствующие параметры:
При нарезке, если вы не учитываете любой параметр, Python пытается выяснить его автоматически.
Если вы проверите исходный код CPython, вы найдете функцию PySlice_GetIndicesEx, которая вычисляет индексы для среза для любых заданных параметров. Вот логический эквивалентный код в Python.
Эта функция принимает объект Python & amp; необязательные параметры для нарезки и начала возврата, остановки, шага & amp; длина среза для запрошенного фрагмента.
def py_slice_get_indices_ex(obj, start=None, stop=None, step=None):
length = len(obj)
if step is None:
step = 1
if step == 0:
raise Exception("Step cannot be zero.")
if start is None:
start = 0 if step > 0 else length - 1
else:
if start < 0:
start += length
if start < 0:
start = 0 if step > 0 else -1
if start >= length:
start = length if step > 0 else length - 1
if stop is None:
stop = length if step > 0 else -1
else:
if stop < 0:
stop += length
if stop < 0:
stop = 0 if step > 0 else -1
if stop >= length:
stop = length if step > 0 else length - 1
if (step < 0 and stop >= start) or (step > 0 and start >= stop):
slice_length = 0
elif step < 0:
slice_length = (stop - start + 1)/(step) + 1
else:
slice_length = (stop - start - 1)/(step) + 1
return (start, stop, step, slice_length)
Это интеллект, который присутствует за фрагментами. Поскольку Python имеет встроенную функцию, называемую slice, вы можете передать некоторые параметры & amp; проверьте, насколько он разумно вычисляет отсутствующие параметры.
In [21]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']
In [22]: s = slice(None, None, None)
In [23]: s
Out[23]: slice(None, None, None)
In [24]: s.indices(len(alpha))
Out[24]: (0, 6, 1)
In [25]: range(*s.indices(len(alpha)))
Out[25]: [0, 1, 2, 3, 4, 5]
In [26]: s = slice(None, None, -1)
In [27]: range(*s.indices(len(alpha)))
Out[27]: [5, 4, 3, 2, 1, 0]
In [28]: s = slice(None, 3, -1)
In [29]: range(*s.indices(len(alpha)))
Out[29]: [5, 4]
Примечание: Это сообщение изначально написано в моем блоге http://www.avilpage.com/2015/03/a-slice-of -python-интеллект-behind.html
Если это разрешено, вы можете написать это:
*bb = new Base;
И c
в конечном итоге укажет на экземпляр Base
. Плохо.