[Avg. reading time: 20 minutes]

Functional Programming Concepts

Functional programming in Python emphasizes the use of functions as first-class citizens, immutability, and declarative code that avoids changing state and mutable data.

def counter():
    count = 0  # Initialize the state
    count += 1
    return count

print(counter())
print(counter())
print(counter())

Regular functions internal State & mutable data

def counter():
    # Define an internal state using an attribute
    if not hasattr(counter, "count"):
        counter.count = 0  # Initialize the state

    # Modify the internal state
    counter.count += 1
    return counter.count

print(counter())
print(counter())
print(counter())

Internal state & immutability

Example without Lambda

increment = lambda x: x + 1

print(increment(5))  # Output: 6
print(increment(5))  # Output: 6

Using Lambda

Lambda functions as a way to write quick, one-off functions without defining a full function using def.

Example without Lambda

def square(x):
    return x ** 2

print(square(4))

Using Lambda

square = lambda x: x ** 2
print(square(4))

Without Lambda

def get_age(person):
    return person['age']

people = [
    {'name': 'Alice', 'age': 30},
    {'name': 'Bob', 'age': 25},
    {'name': 'Charlie', 'age': 35}
]

# Using a defined function to sort
sorted_people = sorted(people, key=get_age)
print(sorted_people)

Using Lambda

people = [
    {'name': 'Alice', 'age': 30},
    {'name': 'Bob', 'age': 25},
    {'name': 'Charlie', 'age': 35}
]

# Using a lambda function to sort
sorted_people = sorted(people, key=lambda person: person['age'])
print(sorted_people)

Map, Filter, Reduce Functions

Map, filter, and reduce are higher-order functions in Python that enable a functional programming style, allowing you to work with data collections in a more expressive and declarative manner.

Map

The map() function applies a given function to each item of an iterable (like a list or tuple) and returns an iterator with the results.

Map Without Functional Approach

numbers = [1, 2, 3, 4, 5]
squares = []
for num in numbers:
    squares.append(num ** 2)
print(squares)  # Output: [1, 4, 9, 16, 25]

Map With Lambda and Map

numbers = [1, 2, 3, 4, 5]
squares = list(map(lambda x: x ** 2, numbers))
print(squares)  # Output: [1, 4, 9, 16, 25]

Filter

The filter() function filters items out of an iterable based on whether they meet a condition defined by a function, returning an iterator with only those elements for which the function returns True.

Filter Without Functional Approach

numbers = [1, 2, 3, 4, 5]
evens = []
for num in numbers:
    if num % 2 == 0:
        evens.append(num)
print(evens)  # Output: [2, 4]

Filter using Functional Approach

numbers = [1, 2, 3, 4, 5]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # Output: [2, 4]

Reduce

The reduce() function, from the functools module, applies a rolling computation to pairs of values in an iterable. It reduces the iterable to a single accumulated value.

At the same time, in many cases, simpler functions like sum() or loops may be more readable.

Reduce Without Functional Approach

  • First, 1 * 2 = 2
  • Then, 2 * 3 = 6
  • Then, 6 * 4 = 24
  • Then, 24 * 5 = 120
numbers = [1, 2, 3, 4, 5]
product = 1
for num in numbers:
    product *= num
print(product)  # Output: 120

Reduce With Lambda

from functools import reduce

numbers = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, numbers)
print(product)  # Output: 120

Using an Initliazer

from functools import reduce

numbers = [1, 2, 3]

# Start with an initial value of 10
result = reduce(lambda x, y: x + y, numbers, 10)
print(result)  
# Output: 16

Using SUM() instead of Reduce()

# So its not necessary to use Reduce all the time :)

numbers = [1, 2, 3, 4, 5]

# Using sum to sum the list
result = sum(numbers)
print(result)  # Output: 15

String Concatenation

from functools import reduce

words = ['Hello', 'World', 'from', 'Python']

result = reduce(lambda x, y: x + ' ' + y, words)
print(result) 
# Output: "Hello World from Python"

List Comprehension and Generators

List Comprehension

List comprehension offers a shorter syntax when you want to create a new list based on the values of an existing list.

Generates the entire list in memory at once, which can consume a lot of memory for large datasets.

Uses: [ ]

Without List Comprehension

numbers = [1, 2, 3, 4, 5]
squares = []
for num in numbers:
    squares.append(num ** 2)
print(squares)

With List Comprehensions

numbers = [1, 2, 3, 4, 5]
squares = [x ** 2 for x in numbers]
print(squares)  

List Generator

Generator expressions are used to create generators, which are iterators that generate values on the fly and yield one item at a time.

Generator expressions generate items lazily, meaning they yield one item at a time and only when needed. This makes them much more memory efficient for large datasets.

Uses: ( )

numbers = [1, 2, 3, 4, 5]
squares = (x ** 2 for x in numbers)
print(sum(squares))  # Output: 55
numbers = [1, 2, 3, 4, 5]
squares = (x ** 2 for x in numbers)
print(list(squares))

Best suited

  • Only one line is in memory at a time.
  • Suitable for processing large or infinite data streams.

#functional #lambda #generator #comprehensionVer 5.5.3

Last change: 2025-10-15