Передача аргументов и lambda
Частый спорный вопрос: Python передаёт аргументы по значению или по ссылке? И зачем нужны lambda.
Python использует передачу по ссылке на объект (call by object reference): в функцию попадает ссылка на тот же объект, но переприсваивание имени внутри функции наружу не видно.
Вопрос: по ссылке или по значению?
Чёткий ответ. Ни то, ни другое в чистом виде. Функция получает ссылку на объект. Если объект изменяемый и вы меняете его на месте — изменение видно снаружи. Если вы переприсваиваете имя внутри — снаружи ничего не меняется.
def modify_list(lst):
lst.append(99) # меняем объект на месте — видно снаружи
def reassign(lst):
lst = [0, 0, 0] # переприсваиваем локальное имя — наружу не видно
def modify_int(n):
n += 100 # int неизменяем — создаётся новый объект
data = [1, 2, 3]
modify_list(data)
print("после modify_list:", data)
reassign(data)
print("после reassign: ", data)
num = 5
modify_int(num)
print("после modify_int: ", num)
Вывод:
после modify_list: [1, 2, 3, 99] после reassign: [1, 2, 3, 99] после modify_int: 5
modify_list изменил объект на месте — снаружи видно. reassign просто переназначил локальное имя — оригинал не тронут. modify_int работает с неизменяемым числом, поэтому снаружи num остался 5.
lambda: анонимная функция-выражение
lambda — короткая функция из одного выражения без имени. Полезна там, где функция нужна «на один раз»: ключ сортировки, аргумент map/filter.
square = lambda x: x * x
print(square(5))
people = [("Аня", 30), ("Боб", 25), ("Ева", 35)]
by_age = sorted(people, key=lambda p: p[1])
print(by_age)
Вывод:
25
[('Боб', 25), ('Аня', 30), ('Ева', 35)]
Когда lambda, а когда def
lambda— для короткого выражения, передаваемого как аргумент (ключ сортировки, колбэк).def— когда есть имя, несколько строк, документация или ветвления.
words = ["banana", "kiwi", "apple", "fig"]
print(sorted(words, key=lambda w: len(w))) # по длине
print(sorted(words, key=len)) # то же без lambda — функция уже есть
Вывод:
['fig', 'kiwi', 'apple', 'banana'] ['fig', 'kiwi', 'apple', 'banana']
Итог
- Python передаёт ссылку на объект: правка mutable на месте видна снаружи, переприсваивание — нет.
- Неизменяемые аргументы (числа, строки) функция «изменить» не может.
lambda— короткая безымянная функция-выражение для одноразового использования.
Проверьте себя
1. Что увидит вызывающий код после функции, которая делает lst.append(99)?
AИзменение видно — список общий
BИзменение не видно
CОшибку
DСписок станет None
2. Почему modify_int(num) с n += 100 не меняет num снаружи?
Aint передаётся копией байтов
Bint неизменяем: n += 100 создаёт новый объект, имя снаружи не трогается
CЭто баг
DНужно вернуть значение через global
3. Для чего обычно используют lambda?
AДля многострочных функций с документацией
BКак короткое выражение-аргумент, например ключ сортировки
CДля определения классов
DДля импорта модулей