Types of functions in Python

There are basically three types of functions you can use:

  • Traditional Functions
  • Lambda Functions
  • Built-in Functions

Traditional Functions

These are the standard functions you can declare in Python. They have a name, can receive arguments, and optionally have a return statement.

def print_hello_world(times: int) -> None:
    print("Hello World!\n" *  times)
    return

TIP

You can add decorators to traditional functions.

Lambda Functions

Lambda functions are small, anonymous functions defined in a single line. They’re useful for passing simple functions as arguments to functions like map() or filter(), or when you need a short function to be used just once.

# Traditional function
def square(x):
    return x**2
 
# Lambda function
square = lambda x: x**2

Lambda functions are conceptually similar to anonymous functions found in other programming languages, like JavaScript’s arrow functions (() => {}).

TIP

Use lambda functions for simple, one-line operations passed as arguments (e.g., sorting with custom keys, mapping simple transformations).

Built-in Functions

Python has many built-in functions that I found to be very useful, and should be used as much as possible:

  • enumerate adds a counter to an iterable:
    for index, value in enumerate(['a', 'b', 'c']):
        print(f"{index}: {value}")  # 0: a, 1: b, 2: c
  • zip combines multiple iterables into tuples:
    names = ['Alice', 'Bob']
    scores = [85, 92]
    for name, score in zip(names, scores):
        print(f"{name}: {score}")  # Alice: 85, Bob: 92
  • sorted returns a sorted list from an iterable:
    sorted([3, 1, 4, 1, 5], reverse=True)  # [5, 4, 3, 1, 1]
    sorted(['banana', 'apple'], key=len)  # ['apple', 'banana']
  • sum, min, and max are aggregate functions for iterables:
    sum([1, 2, 3, 4, 5])  # 15
    min([3, 1, 4, 1, 5])  # 1
    max([3, 1, 4, 1, 5])  # 5
  • any and all are boolean aggregation:
    any([False, False, True])  # True (at least one is true)
    all([True, True, True])    # True (all are true)
  • isinstance checks the type for a given input:
    isinstance(42, int)        # True
    isinstance('hello', str)   # True
  • map applies a function to each item within an iterable:
    list(map(str.upper, ['hello', 'world']))  # ['HELLO', 'WORLD']

INFO

Iterables are objects that can be iterated over, such as lists, tuples, and strings. You can use the iter() function to create an iterator from an iterable.

TIP

These built-in functions are optimized in C, which makes them faster and part of The Pythonic Way of coding.

Variable-Length Arguments

In Python, *args and **kwargs are used in function definitions to allow for variable-length arguments. They stand for “arguments” and “keyword arguments”, respectively.

def my_function(*args, **kwargs):
    for arg in args:
        print(arg)
    for key, value in kwargs.items():
        print(f"{key}: {value}")

They are useful when you wish to make a function more flexible so it can handle a varying number of arguments, or when you don’t really know how many or which arguments will be provided beforehand.

TIP

Use *args for variable positional arguments and **kwargs for variable keyword arguments. Common use cases include decorators and APIs.

Generators

Generators are a way to create iterators in Python. They allow you to iterate over a sequence of values without having to store them all in memory at once. This is particularly useful when working with large data sets, as it can help reduce memory usage and improve performance.

Generators are defined using functions that use the yield keyword to produce a sequence of values:

def count_up_to(n):
    count = 1
    while count <= n:
        yield count
        count += 1

Using a generator in this example allows you to count up to millions and still have performance while running it, since it only stores one value at a time in memory. You can use it in a loop to iterate over the values it produces:

for number in count_up_to(5):
    print(number)

This is basically how the range() function works in Python 3, which returns a generator instead of a list.

NOTE

This is only accomplished thanks to Python’s yield keyword.