Python3 - Functions Flashcards
Pure Functions
Have no side effects.
output of a pure functions is determined entirely by input, and do not modify any state outside of itself (even print modifies the state of the console).
comprehensible, easier to reason, debug and parallelize (execute multiple at the same time)
def square (x): return x * x
Higher-Order Functions
take one or more function as an argument, or return one or more function as a result.
list ( map ( lambda x: x * x, [1, 2, 3]))
Recursion
Programming technique where function calls itself.
takes base case (case where recursion finishes) and recursive case (reason to call itself)
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n-1)
Nested Function
function inside function.
helps encapsulate code to be easier to read and maintain, but can be harder to understand if overused.
creates closures, comprehensions and decorators
Closure
creates functions with access to variables in surrounding scope. creates reusable functions that work with different data
(generators, decorators, higher order functions.
def make_multiplier(factor):
def multiplier(number):
return number * factor
return multiplier
Enclosing
Ability of a nested function to access variables defined in enclosing function (surrounding scope)
Nonlocal Variable
variable set to be accessible beyond current scope (nested function variable defined with nonlocal keyword)
*args and **kwargs
permit variable number of arguments as parameters.
kwargs permits key-value pairs.
def print_args(*args):
for arg in args:
print(arg)
def prints_kwargs( **kwargs):
for key, value in kwargs.items():
print(key, value)
lambda functions
one-lined function defined using lambda keyword.
“anonymous” function, quick and compact. takes a single expresison and any number of arguments, ad returns the result of the expression, per argument. good for map, filter and reduce.
squares = (lambda x: x * x, numbers_list)
Comprehensions
concise way to make lists, sets, dictionaries and generators.
used to create new sequences from existing sequences.
squares_list = [x * x for x in range(1, 11) ]
even_numbers_set = { x for x in range(1, 11) if x % 2 == 0 }
squares_dict = {x: x * x for x in range(10)}
evens_only_squares_dict = {x: x * x for x in range(10) if x % 2 == 0}
> > > evens_only_squares_dict
{0: 0, 4: 16, 8: 64}
Decorators
function that returns another function as an argument, returns a modified version of the function. efined using @symbol.
@make_pretty
def ordinary():
print(something”)
built-in functions:
Map
Filter
reduce
numbers = [1, 2, 3, 4, 5]
squared_numbers = map(lambda x: x * x, numbers)
# Output: [1, 4, 9, 16, 25]
even_numbers = filter(lambda x: x % 2 == 0, numbers)
# Output: [2, 4]
product_of_numbers = reduce(lambda x, y: x * y, numbers)
# Output: 120
What is the difference between “expression” and “statement”
expression is a combination of variables the evaluates to a single value,
but a statement has a side effect (x = 2 * 2 vs 2 * 2)
When should you use lambda, when should you not?
yes for one-off functions. NOT for loops.
Write a program to remove specific words from a given list using lambda
def remove_words(lst, remove_from_list):
return list(filter(lambda word: word not in remove_from_list, lst))
my_list = [“Python”, “C”, “BashScript”, “JavaScript”, “COBOL”, “Java”]
remove_list = [“COBOL”, “Java”]
filtered_list = remove_words(my_list, remove_list)