Функция — это как магия: даёшь аргументы — получаешь результат. И не нужно жертвовать барашком.
🐣 Разминка: Что такое функция?
Функция — это именованный блок кода, который можно вызывать повторно, передавать данные и даже возвращать другие функции!
def say_hello(name):
return f"Hello, {name}!"
print(say_hello("Pythonista")) # Hello, Pythonista!
📌 Что здесь происходит:
- def — ключевое слово для объявления функции.
- name — параметр.
- return — то, что "уходит наружу".
- Функция возвращает строку, а не просто печатает её (это плюсик к карме).
🍝 Параметры и аргументы: варим функции "аль денте"
Python умеет работать с:
- позиционными аргументами,
- аргументами по умолчанию,
- *args (много позиционных),
- **kwargs (много именованных).
def cook_pasta(type="spaghetti", *toppings, **sauce_options):
print(f"Pasta type: {type}")
print("Toppings:", toppings)
print("Sauce options:", sauce_options)
cook_pasta("penne", "cheese", "basil", sauce="pesto", spicy=True)
Вывод:
Pasta type: penne
Toppings: ('cheese', 'basil')
Sauce options: {'sauce': 'pesto', 'spicy': True}
🧪 Вложенные функции и замыкания (closures)
Функции в Python — это объекты. И можно делать функции, которые возвращают функции! (Вау!)
def multiplier(factor):
def multiply(x):
return x * factor
return multiply
double = multiplier(2)
print(double(5)) # 10
💡 Что здесь интересного:
- factor запоминается даже после выхода из multiplier.
- Это называется замыкание — полезно для фабрик функций и лямбд.
⚡ Лямбда-функции
Они компактны, быстры и идеально подходят для однострочных выражений.
square = lambda x: x * x
print(square(4)) # 16
Лайфхак: Не стоит злоупотреблять — когда становится нечитаемо, пора писать def.
🧙♂️ Продвинутый уровень: Декораторы
Если хочешь добавить магии до и после выполнения функции — используй декораторы.
def logger(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__}...")
result = func(*args, **kwargs)
print("Done!")
return result
return wrapper
@logger
def greet(name):
print(f"Hi, {name}!")
greet("Alice")
🛠️ Собеседование: задачи и решения
🧩 Задача 1: Факториал рекурсивно и итеративно
Вопрос: Напиши функцию для вычисления факториала. Сделай и так, и так.
# Рекурсивно
def factorial_recursive(n):
return 1 if n == 0 else n * factorial_recursive(n - 1)
# Итеративно (без переполнения стека)
def factorial_iterative(n):
result = 1
for i in range(2, n + 1):
result *= i
return result
print(factorial_iterative(5)) # 120
✅ Оптимально: использовать итерацию — нет риска переполнения стека.
🧩 Задача 2: Проверка на палиндром
Условие: строка читается одинаково слева направо и наоборот?
def is_palindrome(s):
return s == s[::-1]
print(is_palindrome("level")) # True
🔍 Оптимальность: срез работает быстро, читаемо и эффективно.
🧩 Задача 3: Поиск уникальных слов в списке
Условие: вернуть список уникальных слов, не теряя порядок.
def unique_words(words):
seen = set()
return [w for w in words if not (w in seen or seen.add(w))]
print(unique_words(["apple", "banana", "apple", "cherry", "banana"]))
# ['apple', 'banana', 'cherry']
🎯 Оптимальность: O(n), использование set + list comprehension с add().
🧩 Задача 4: Функция с мемоизацией (кешированием)
from functools import lru_cache
@lru_cache(maxsize=None)
def fibonacci(n):
if n in (0, 1):
return n
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(30)) # 832040
🧠 Мемоизация — залог выживания в рекурсивных задачах на собесе.
🤹 Немного юмора напоследок:
HR: Чем отличается функция от метода?
Вы: У метода больше ответственности и меньше свободы — он привязан к объекту, как вы к дедлайнам.
📌 Выводы:
Что нужно знать новичку: def, return, аргументы, вызов функции
Продвинутый уровень: lambda, *args, **kwargs, вложенные функции
Профи: собесдекораторы, мемоизация, оптимизация, замыкания