Передает ли оператор присваивания ссылку на аргумент в функциях Python? [Дубликат]

Это довольно просто:

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 содержит только один элемент, вы получаете пустой список вместо ошибки. Иногда вы предпочитаете ошибку, поэтому вы должны знать, что это может случиться.

13
задан Fred Foo 20 July 2012 в 21:20
поделиться

1 ответ

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 имеют определенное количество накладных расходов только сами по себе (для настройки кадра выполнения и т. д.). Если функция вызывается много раз, эти издержки могут вызвать заметное влияние производительности. Таким образом, разделение одной функции на многие может по-прежнему оказывать влияние на производительность, поскольку каждый дополнительный вызов функции добавит некоторые служебные данные.

16
ответ дан BrenBarn 25 August 2018 в 05:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: