Python Fundamentals contents
Functions
Defining functions, parameters and return values, default and keyword arguments, *args/**kwargs, scope and lambda.
Read first: Loops
A function is a named, reusable block of code. It removes duplication and lets you name an idea (is_prime(n)) instead of repeating its steps.
def greet(name):
return f"Hello, {name}!"
message = greet("Ana")
assert message == "Hello, Ana!"def defines the function; calling it runs the body; return hands a value back and ends the function. A function without return returns None.
Parameters and arguments
Parameters are the names in the definition; arguments are the values you pass.
def power(base, exponent=2): # exponent has a default value
return base ** exponent
assert power(5) == 25 # default used
assert power(2, 10) == 1024 # positional
assert power(exponent=3, base=2) == 8 # keyword: order does not matterParameters with defaults must come after those without. Never use a mutable default such as []:
def bad_append(x, target=[]): # the SAME list is reused on every call!
target.append(x)
return target
bad_append(1)
assert bad_append(2) == [1, 2] # surprise
def good_append(x, target=None):
if target is None:
target = []
target.append(x)
return target
good_append(1)
assert good_append(2) == [2]Any number of arguments
def total(*numbers): # collected into a tuple
return sum(numbers)
def describe(**info): # collected into a dict
return ", ".join(f"{k}={v}" for k, v in sorted(info.items()))
assert total(1, 2, 3, 4) == 10
assert describe(b=2, a=1) == "a=1, b=2"
values = [1, 2, 3]
assert total(*values) == 6 # * unpacks a list into argumentsReturning several values
A function can return a tuple and the caller can unpack it:
def min_max(items):
return min(items), max(items)
lo, hi = min_max([4, 9, 1])
assert (lo, hi) == (1, 9)Scope
A variable created inside a function is local: it exists only during the call. A function can read a global variable, but assigning to it creates a new local one unless you say global.
counter = 0
def bump():
global counter
counter += 1
bump(); bump()
assert counter == 2Arguments are passed by object reference: a function that mutates a list argument changes the caller's list, while reassigning the parameter does not.
def add_item(lst):
lst.append("x") # mutates the caller's list
def rebind(lst):
lst = ["new"] # only rebinds the local name
data = []
add_item(data)
rebind(data)
assert data == ["x"]Lambda functions
A lambda is a tiny anonymous function limited to a single expression. It is mostly used as a key for sorting.
square = lambda x: x * x
assert square(6) == 36
people = [("Ana", 30), ("Bob", 25), ("Cara", 35)]
assert sorted(people, key=lambda p: p[1])[0] == ("Bob", 25)
assert sorted(people, key=lambda p: -p[1])[0] == ("Cara", 35)Docstrings and clean design
Put a string as the first statement to document a function. Keep functions short and give each one a single job.
def is_prime(n):
"""Return True if n is a prime number."""
if n < 2:
return False
return all(n % d for d in range(2, int(n ** 0.5) + 1))
assert is_prime(97) and not is_prime(91)
assert is_prime.__doc__ == "Return True if n is a prime number."Exercises
- Write
is_even(n)andfactorial(n)(with a loop). - Write
count_vowels(text). - Write
gcd(a, b)using a loop. - Write a function that returns both the smallest and the second smallest element of a list.
- Write
mean(*numbers)accepting any number of arguments.