Package logic into reusable functions with parameters and return values, use default and keyword arguments, write one-line lambdas, and understand variable scope.
Why: a function is a named, reusable block of code. Define it with def, give it inputs (parameters), and hand back a result with return. Calling it runs the code with the inputs you pass.
def greet(name):
return f'Hello, {name}!'
message = greet('Ada') # call it
print(message) # Hello, Ada!Why: a default value lets a parameter be optional. Naming arguments when you call (keyword arguments) makes the call clearer and lets you skip over optional ones.
def make_user(name, role='member', active=True):
return {'name': name, 'role': role, 'active': active}
print(make_user('Ada')) # uses both defaults
print(make_user('Bob', role='admin')) # name by position, role by keyword
print(make_user('Cleo', active=False)) # skip role, set activeWhy: sometimes you do not know how many arguments will be passed. *args collects extra positional arguments into a tuple; **kwargs collects extra named ones into a dict.
def total(*args):
return sum(args)
print(total(1, 2, 3, 4)) # 10
def describe(**kwargs):
for key, value in kwargs.items():
print(f'{key}: {value}')
describe(name='Ada', age=30)
# name: Ada
# age: 30Why: Python ships with handy functions you can use without importing anything. You have already met print() and len() — here are a few more you will use constantly.
nums = [4, 1, 7, 3]
print(len(nums)) # 4
print(sum(nums)) # 15
print(max(nums)) # 7
print(min(nums)) # 1
print(sorted(nums)) # [1, 3, 4, 7] (new sorted list)
print(abs(-5)) # 5Why: a lambda is a small function written in one line, without a name. It is handy as a quick argument to functions like sorted() that take another function.
double = lambda x: x * 2
print(double(5)) # 10
# most common use: a sort key
people = [('Ada', 30), ('Bob', 25)]
people.sort(key=lambda person: person[1]) # sort by age
print(people) # [('Bob', 25), ('Ada', 30)]Why: a variable created inside a function is "local" — it only exists there. Code outside cannot see it. This keeps functions self-contained and avoids accidental clashes. Python looks up names Local, then Enclosing, then Global, then Built-in (the LEGB rule).
total = 0 # global
def add_item(price):
tax = price * 0.1 # local — vanishes when the function ends
return price + tax
print(add_item(100)) # 110.0
# print(tax) # ERROR: tax doesn't exist out here