Это довольно просто:
a[start:end] # items start through end-1
a[start:] # items start through the rest of the array
a[:end] # items from the beginning through end-1
a[:] # a copy of the whole array
Также есть значение step
, которое можно использовать с любым из вышеперечисленных способов:
a[start:end:step] # start through not past end, by step
Ключевая точка помните, что значение :end
представляет первое значение, которое не в выбранном фрагменте. Таким образом, разница между end
и start
- это количество выбранных элементов (если step
равно 1, по умолчанию).
Другая особенность заключается в том, что start
или end
могут быть отрицательным числом, что означает, что он отсчитывается от конца массива, а не от начала. Итак:
a[-1] # last item in the array
a[-2:] # last two items in the array
a[:-2] # everything except the last two items
Аналогично, step
может быть отрицательным числом:
a[::-1] # all items in the array, reversed
a[1::-1] # the first two items, reversed
a[:-3:-1] # the last two items, reversed
a[-3::-1] # everything except the last two items, reversed
Python является добрым к программисту, если есть меньше предметов, чем вы просите. Например, если вы запрашиваете a[:-2]
, а a
содержит только один элемент, вы получаете пустой список вместо ошибки. Иногда вы предпочитаете ошибку, поэтому вы должны знать, что это может случиться.
Python использует систему, иногда называемую call-by-object . При передаче аргументов функции не копируется. Имена аргументов функции локально связаны внутри тела функции с теми же объектами, что и в вызове функции.
Это отличается от того, что большинство людей думает как «вызов по значению», потому что оно Скопируйте объекты. Но он также отличается от «вызова по ссылке», потому что ссылка на объект --- новое имя связано, но с тем же объектом. Это означает, что вы можете мутировать переданный объект, но переупорядочение имени внутри функции не имеет эффекта вне функции. Простой пример разницы:
>>> def func(x):
... x[0] = 2 # Mutating the object affects the object outside the function
>>> myList = [1]
>>> func(myList)
>>> myList # myList has changed
[2]
>>> def func(x):
... x = 2 # rebinding name has no effect outside the function
>>> myList = [1]
>>> func(myList)
>>> myList # myList is unaffected
[1]
. Мой простой способ мышления об этом состоит в том, что назначение нечетному имени --- то есть инструкции формы name = value
--- совершенно разные от всего остального в Python. Только способ работать с именами, а не по значениям, это name = value
. (Есть исключения из-за этого, например, fucking with globals()
и т. Д., Но это опасная территория). В частности name = value
отличается от obj.prop = value
, obj[0] = value
, obj += value
и других аналогичных вещи, которые выглядят как присваивание, но фактически работают с объектами, а не с именами.
Тем не менее, вызовы функций в Python имеют определенное количество накладных расходов только сами по себе (для настройки кадра выполнения и т. д.). Если функция вызывается много раз, эти издержки могут вызвать заметное влияние производительности. Таким образом, разделение одной функции на многие может по-прежнему оказывать влияние на производительность, поскольку каждый дополнительный вызов функции добавит некоторые служебные данные.