A Python generator is a piece of specialized code able to produce a series of values, and to control the iteration process.
generators are very often called iterators
A function returns one, well-defined value – it may be the result of a more or less complex evaluation of, something like a polynomial, and is invoked once – only once. A generator returns a series of values, and in general, is (implicitly) invoked more than once.
The iterator protocol is a way in which an object should behave to conform to the rules imposed by the context of the for and in statements.
An object conforming to the iterator protocol is called an iterator.
An iterator must provide two methods:
__iter__() and __next__()
In Python, generators are implemented as objects with the __iter__() and __next__() methods defined inside them.
__iter__() which should return the object itself and which is invoked once (it's needed for Python to successfully start the iteration)
__next__() which is intended to return the next value (first, second, and so on) of the desired series – it will be invoked by the for/in statements in order to pass through the next iteration; if there are no more values to provide, the method should raise the StopIteration exception.
ou may think of the yield keyword as a smarter sibling of the return statement, with one essential difference.
def fun(n):
for i in range(n):
return i
It looks strange, doesn't it? It's clear that the for loop has no chance to finish its first execution, as the return will break it irrevocably.
Moreover, invoking the function won't change anything - the for loop will start from scratch and will be broken immediately.
We can say that such a function is not able to save and restore its state between subsequent invocations. This also means that a function like this cannot be used as a generator.
yield
Instead of return, turns the function into a generator
The previous function (the one with the return statement) may only be invoked explicitly, and must not be used as a generator
A generator function is a regular function that contains at least one occurrence of the yieldkeyword.
The list() function can transform a series of subsequent generator invocations into a real list
The lambda function is a concept borrowed from mathematics, more specifically, from a part called the Lambda calculus, but these two phenomena are not the same.
Mathematicians use the Lambda calculus in many formal systems connected with logic, recursion, or theorem provability. Programmers use the lambda function to simplify the code, to make it clearer and easier to understand.
A lambda function is a function without a name (you can also call it an anonymous function). Of course, such a statement immediately raises the question: how do you use anything that cannot be identified?
Fortunately, it's not a problem, as you can name such a function if you really need, but, in fact, in many cases the lambda function can exist and work while remaining fully incognito.
Such a clause returns the value of the expression when taking into account the current value of the current lambda argument.
The most interesting thing about lambdas is that you can use them in their pure form – as anonymous parts of code intended to evaluate a result.
print_function() function takes two parameters:
the first, a list of arguments for which we want to print the results;
the second, a function which should be invoked as many times as the number of values that are collected inside the first parameter.