02_functional_programming.py
Python/03_advanced_level/02_functional_programming.py
# Functional Programming Examples
from functools import reduce, partial, wraps
from typing import List, Callable, Any, Iterator
import operator
print("Functional Programming Examples")
print("=" * 35)
# 1. Higher-Order Functions
print("1. Higher-Order Functions")
print("-" * 25)
def apply_operation(numbers: List[int], operation: Callable[[int], int]) -> List[int]:
"""Apply an operation to each number in the list."""
return [operation(x) for x in numbers]
def square(x: int) -> int:
return x ** 2
def cube(x: int) -> int:
return x ** 3
def double(x: int) -> int:
return x * 2
# Test higher-order functions
numbers = [1, 2, 3, 4, 5]
print(f"Original numbers: {numbers}")
print(f"Squared: {apply_operation(numbers, square)}")
print(f"Cubed: {apply_operation(numbers, cube)}")
print(f"Doubled: {apply_operation(numbers, double)}")
# 2. Lambda Functions
print("\n2. Lambda Functions")
print("-" * 20)
# Lambda functions for common operations
'''
def add(x, y):
return x + y
def multiply(x, y):
return x * y
def is_even(x):
return x % 2 == 0
def is_positive(x):
return x > 0
'''
add = lambda x, y: x + y
multiply = lambda x, y: x * y
is_even = lambda x: x % 2 == 0
is_positive = lambda x: x > 0
# Test lambda functions
print(f"Add 5 + 3: {add(5, 3)}")
print(f"Multiply 4 * 6: {multiply(4, 6)}")
print(f"Is 7 even? {is_even(7)}")
print(f"Is -5 positive? {is_positive(-5)}")
# Lambda with map, filter, reduce
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# higher-order function example
# Map with lambda
squared = list(map(lambda x: x ** 2, numbers))
## [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] -- squared list
print(f"Squared numbers: {squared}")
# Filter with lambda
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(f"Even numbers: {even_numbers}")
# Reduce with lambda
sum_of_squares = reduce(lambda x, y: x + y, squared)
print(f"Sum of squares: {sum_of_squares}")
# 3. Map, Filter, and Reduce
print("\n3. Map, Filter, and Reduce")
print("-" * 25)
# Map examples
def square(x):
return x ** 2
def to_string(x):
return str(x)
numbers = [1, 2, 3, 4, 5]
# Map with named function
squared = list(map(square, numbers))
print(f"Squared: {squared}")
# Map with lambda
strings = list(map(lambda x: str(x), numbers))
print(f"Strings: {strings}")
# Map with multiple iterables
list1 = [1, 2, 3]
list2 = [4, 5, 6]
sums = list(map(lambda x, y: x + y, list1, list2))
print(f"Sums: {sums}")
# Filter examples
def is_even(x):
return x % 2 == 0
def is_positive(x):
return x > 0
numbers = [-2, -1, 0, 1, 2, 3, 4, 5]
# Filter with named function
even_numbers = list(filter(is_even, numbers))
print(f"Even numbers: {even_numbers}")
# Filter with lambda
positive_numbers = list(filter(lambda x: x > 0, numbers))
print(f"Positive numbers: {positive_numbers}")
# Filter with None (removes falsy values)
mixed_values = [0, 1, None, 2, "", 3, False, 4]
truthy_values = list(filter(None, mixed_values))
print(f"Truthy values: {truthy_values}")
# Reduce examples
def add(x, y):
return x + y
def multiply(x, y):
return x * y
def find_max(x, y):
return x if x > y else y
numbers = [1, 2, 3, 4, 5]
# Reduce with named function
sum_result = reduce(add, numbers)
print(f"Sum: {sum_result}")
# Reduce with lambda
product = reduce(lambda x, y: x * y, numbers)
print(f"Product: {product}")
# Reduce with initial value
sum_with_initial = reduce(add, numbers, 10)
print(f"Sum with initial 10: {sum_with_initial}")
# Reduce to find maximum
max_value = reduce(find_max, numbers)
print(f"Maximum: {max_value}")
# 4. Function Composition
print("\n4. Function Composition")
print("-" * 22)
def compose(*functions):
"""Compose multiple functions."""
def composed(x):
for func in reversed(functions):
x = func(x)
return x
return composed
def add_one(x):
return x + 1
def multiply_by_two(x):
return x * 2
def square(x):
return x ** 2
# Compose functions
composed_func = compose(square, multiply_by_two, add_one)
result = composed_func(3)
print(f"Compose result: {result}")
# Manual composition
manual_result = square(multiply_by_two(add_one(3)))
print(f"Manual composition: {manual_result}")
# 5. Partial Functions
print("\n5. Partial Functions")
print("-" * 20)
def multiply(x, y):
return x * y
# Create partial functions
double = partial(multiply, 2)
triple = partial(multiply, 3)
print(f"Double 5: {double(5)}")
print(f"Triple 4: {triple(4)}")
# Partial with keyword arguments
def power(base, exponent):
return base ** exponent
square = partial(power, exponent=2)
cube = partial(power, exponent=3)
print(f"Square of 4: {square(4)}")
print(f"Cube of 3: {cube(3)}")
# 6. Closures
print("\n6. Closures")
print("-" * 12)
def create_multiplier(factor):
"""Create a multiplier function."""
def multiplier(x):
return x * factor
return multiplier
# Create multiplier functions
double = create_multiplier(2)
triple = create_multiplier(3)
quadruple = create_multiplier(4)
print(f"Double 5: {double(5)}")
print(f"Triple 4: {triple(4)}")
print(f"Quadruple 3: {quadruple(3)}")
# Closure with mutable state
def create_counter():
"""Create a counter function."""
count = 0
def counter():
nonlocal count
count += 1
return count
return counter
# Create counter instances
counter1 = create_counter()
counter2 = create_counter()
print(f"Counter1: {counter1()}, {counter1()}, {counter1()}")
print(f"Counter2: {counter2()}, {counter2()}")
# 7. Generator Functions
print("\n7. Generator Functions")
print("-" * 20)
def fibonacci_generator(n):
"""Generate Fibonacci numbers up to n."""
a, b = 0, 1
while a < n:
yield a
a, b = b, a + b
def squares_generator(n):
"""Generate squares up to n."""
for i in range(n):
yield i ** 2
# Test generators
print("Fibonacci numbers:")
for num in fibonacci_generator(20):
print(num, end=" ")
print()
print("Squares:")
for square in squares_generator(10):
print(square, end=" ")
print()
# Generator expressions
squares_gen = (x ** 2 for x in range(10))
print(f"Generator expression: {list(squares_gen)}")
# 8. Iterators and Iterables
print("\n8. Iterators and Iterables")
print("-" * 25)
class NumberRange:
"""Custom iterable class."""
def __init__(self, start, stop, step=1):
self.start = start
self.stop = stop
self.step = step
def __iter__(self):
return NumberRangeIterator(self.start, self.stop, self.step)
class NumberRangeIterator:
"""Iterator for NumberRange."""
def __init__(self, start, stop, step):
self.current = start
self.stop = stop
self.step = step
def __iter__(self):
return self
def __next__(self):
if self.current >= self.stop:
raise StopIteration
value = self.current
self.current += self.step
return value
# Test custom iterable
number_range = NumberRange(0, 10, 2)
print(f"Custom range: {list(number_range)}")
# 9. Functional Data Structures
print("\n9. Functional Data Structures")
print("-" * 30)
class ImmutableList:
"""Immutable list implementation."""
def __init__(self, items=None):
self._items = tuple(items) if items else ()
def __getitem__(self, index):
return self._items[index]
def __len__(self):
return len(self._items)
def __iter__(self):
return iter(self._items)
def __repr__(self):
return f"ImmutableList({list(self._items)})"
def append(self, item):
return ImmutableList(self._items + (item,))
def prepend(self, item):
return ImmutableList((item,) + self._items)
def map(self, func):
return ImmutableList(func(x) for x in self._items)
def filter(self, func):
return ImmutableList(x for x in self._items if func(x))
def reduce(self, func, initial=None):
if initial is None:
return reduce(func, self._items)
return reduce(func, self._items, initial)
# Test immutable list
immutable_list = ImmutableList([1, 2, 3, 4, 5])
print(f"Original: {immutable_list}")
# Operations return new instances
doubled = immutable_list.map(lambda x: x * 2)
print(f"Doubled: {doubled}")
evens = immutable_list.filter(lambda x: x % 2 == 0)
print(f"Evens: {evens}")
sum_result = immutable_list.reduce(lambda x, y: x + y)
print(f"Sum: {sum_result}")
# 10. Advanced Functional Patterns
print("\n10. Advanced Functional Patterns")
print("-" * 35)
# Memoization
def memoize(func):
"""Memoization decorator."""
cache = {}
@wraps(func)
def wrapper(*args):
if args in cache:
return cache[args]
result = func(*args)
cache[args] = result
return result
return wrapper
@memoize
def fibonacci(n):
"""Memoized Fibonacci function."""
if n < 2:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
# Test memoization
print(f"Fibonacci(10): {fibonacci(10)}")
print(f"Fibonacci(20): {fibonacci(20)}")
# Currying
def curry(func):
"""Curry a function."""
def curried(*args):
if len(args) >= func.__code__.co_argcount:
return func(*args)
return lambda *more_args: curried(*(args + more_args))
return curried
@curry
def add_three_numbers(a, b, c):
return a + b + c
# Test currying
add_5_and_3 = add_three_numbers(5)(3)
result = add_5_and_3(2)
print(f"Curried addition: {result}")
# Function pipelines
def pipeline(*functions):
"""Create a pipeline of functions."""
def piped(value):
for func in functions:
value = func(value)
return value
return piped
# Create pipeline
process_numbers = pipeline(
lambda x: x * 2, # double
lambda x: x + 1, # add one
lambda x: x ** 2, # square
lambda x: x - 1 # subtract one
)
# Test pipeline
result = process_numbers(3)
print(f"Pipeline result: {result}")
# Manual pipeline
manual_result = 3
manual_result = manual_result * 2
manual_result = manual_result + 1
manual_result = manual_result ** 2
manual_result = manual_result - 1
print(f"Manual pipeline: {manual_result}")
print("\nFunctional Programming examples completed!")
관련 글
01_getting_started.py
01_getting_started.py — python source code from the Python learning materials (Python/01_beginner_level/01_getting_started.py).
글 읽기 →02_core_syntax.py
02_core_syntax.py — python source code from the Python learning materials (Python/01_beginner_level/02_core_syntax.py).
글 읽기 →03_control_flow.py
03_control_flow.py — python source code from the Python learning materials (Python/01_beginner_level/03_control_flow.py).
글 읽기 →04_data_structures.py
04_data_structures.py — python source code from the Python learning materials (Python/01_beginner_level/04_data_structures.py).
글 읽기 →05_functions.py
05_functions.py — python source code from the Python learning materials (Python/01_beginner_level/05_functions.py).
글 읽기 →06_error_handling.py
06_error_handling.py — python source code from the Python learning materials (Python/01_beginner_level/06_error_handling.py).
글 읽기 →