{"id":6085,"date":"2022-05-13T16:31:16","date_gmt":"2022-05-13T14:31:16","guid":{"rendered":"http:\/\/miro.borodziuk.eu\/?p=6085"},"modified":"2026-01-23T15:27:32","modified_gmt":"2026-01-23T14:27:32","slug":"generators-iterators-and-closures","status":"publish","type":"post","link":"http:\/\/miro.borodziuk.eu\/index.php\/2022\/05\/13\/generators-iterators-and-closures\/","title":{"rendered":"Generators, iterators, lambdas and closures;"},"content":{"rendered":"<p>A Python generator is <strong>a piece of specialized code able to produce a series of values, and to control the iteration process<\/strong>. This is why generators are very often called <strong>iterators<\/strong>, and although some may find a very subtle distinction between these two, we&#8217;ll treat them as one.<\/p>\n<p><!--more--><\/p>\n<p>1. An <b>iterator<\/b> is an object of a class providing at least <b>two<\/b> methods (not counting the constructor):<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li><code>__iter__()<\/code> is invoked once when the iterator is created and returns the iterator&#8217;s object <b>itself<\/b>;<\/li>\n<li><code>__next__()<\/code> is invoked to provide the <b>next iteration&#8217;s value<\/b> and raises the <code>StopIteration<\/code> exception when the iteration <b>comes to an end<\/b>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Simple generator example:<\/p>\n<pre class=\"lang:default decode:true \">for i in range(5):\r\n    print(i)<\/pre>\n<p>The <strong>iterator protocol is a way in which an object should behave to conform to the rules imposed by the context of the <code>for<\/code> and <code>in<\/code> statements<\/strong>. An object conforming to the iterator protocol is called an <strong>iterator<\/strong>.<\/p>\n<p>The Fibonacci numbers (Fib<sub>i<\/sub>) are defined as follows:<\/p>\n<p>Fib<sub>1<\/sub> = 1<br \/>\nFib<sub>2<\/sub> = 1<br \/>\nFib<sub>i<\/sub> = Fib<sub>i-1<\/sub> + Fib<sub>i-2<\/sub><\/p>\n<p>In other words:<\/p>\n<ul>\n<li>the first two Fibonacci numbers are equal to 1;<\/li>\n<li>any other Fibonacci number is the sum of the two previous ones (e.g., Fib<sub>3<\/sub> = 2, Fib<sub>4<\/sub> = 3, Fib<sub>5<\/sub> = 5, and so on)<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true \">class Fib:\r\n    def __init__(self, nn):\r\n        print(\"__init__\")\r\n        self.__n = nn\r\n        self.__i = 0\r\n        self.__p1 = self.__p2 = 1\r\n\r\n    def __iter__(self):\r\n        print(\"__iter__\")\r\n        return self\r\n\r\n    def __next__(self):\r\n        print(\"__next__\")\t\t\t\t\r\n        self.__i += 1\r\n        if self.__i &gt; self.__n:\r\n            raise StopIteration\r\n        if self.__i in [1, 2]:\r\n            return 1\r\n        ret = self.__p1 + self.__p2\r\n        self.__p1, self.__p2 = self.__p2, ret\r\n        return ret\r\n\r\n\r\nfor i in Fib(10):\r\n    print(i)<\/pre>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>2. The <strong><code>yield<\/code> <\/strong>statement can be used only inside functions. The <strong><code>yield<\/code><\/strong> statement suspends function execution and causes the function to return the yield&#8217;s argument as a result. Such a function cannot be invoked in a regular way \u2013 its only purpose is to be used as a <b>generator<\/b> (i.e. in a context that requires a series of values, like a <code>for<\/code> loop.)<\/p>\n<p>Take a look at this function:<\/p>\n<pre class=\"lang:default decode:true \">def fun(n):\r\n    for i in range(n):\r\n        return i\r\n<\/pre>\n<p>It&#8217;s clear that the <code>for<\/code> loop has no chance to finish its first execution, as the <code>return<\/code> will break it irrevocably.<\/p>\n<p>Moreover, invoking the function won&#8217;t change anything &#8211; the <code>for<\/code> loop will start from scratch and will be broken immediately.<\/p>\n<p>We can say that such a function is not able to save and restore its state between subsequent invocations.<\/p>\n<p>This also means that a function like this <strong>cannot be used as a generator<\/strong>.<\/p>\n<p>Let&#8217;s replace exactly one word in the code:<\/p>\n<pre class=\"lang:default decode:true \">def fun(n):\r\n    for i in range(n):\r\n        yield i\r\n<\/pre>\n<p>There is one important limitation: such a <strong>function should not be invoked explicitly<\/strong> as &#8211; in fact &#8211; it isn&#8217;t a function anymore; <strong>it&#8217;s a generator object<\/strong>.<\/p>\n<p>The invocation will <strong>return the object&#8217;s identifier<\/strong>, not the series we expect from the generator.<\/p>\n<p>This is how we can use it:<\/p>\n<pre class=\"lang:default decode:true\">def fun(n):\r\n    for i in range(n):\r\n        yield i\r\n\r\nfor v in fun(5):\r\n    print(v)\r\n<\/pre>\n<p><code>0<\/code><br \/>\n<code>1<\/code><br \/>\n<code>2<\/code><br \/>\n<code>3<\/code><br \/>\n<code>4<\/code><\/p>\n<pre class=\"lang:default decode:true\">def powers_of_2(n):\r\n    power = 1\r\n    for i in range(n):\r\n        yield power\r\n        power *= 2\r\n\r\nfor v in powers_of_2(8):\r\n    print(v)\r\n<\/pre>\n<p><code>1<\/code><br \/>\n<code>2<\/code><br \/>\n<code>4<\/code><br \/>\n<code>8<\/code><br \/>\n<code>16<\/code><br \/>\n<code>32<\/code><br \/>\n<code>64<\/code><br \/>\n<code>128<\/code><\/p>\n<p><em>Example.<\/em><\/p>\n<pre class=\"lang:default decode:true\">s = '+' \r\nfor i in range(2): \r\n    s += s \r\n    print(\"s=\", s, end=\"\\n\")<\/pre>\n<p><code>s= ++<\/code><br \/>\n<code>s= ++++<\/code><\/p>\n<pre class=\"lang:default decode:true \">def my_fun(n): \r\n    s = '+' \r\n    for i in range(n): \r\n        s += s \r\n        yield s\r\n        \r\nfor x in my_fun(2): \r\n    print(x, end=\"\") \r\n<\/pre>\n<p><code>++++++<\/code><\/p>\n<p>&nbsp;<\/p>\n<p>3. A <b>conditional expression<\/b> is an expression built using the <code>if-else<\/code> operator. For example:<\/p>\n<div class=\"ace-tm\">\n<div class=\"ace_static_highlight\">\n<div class=\"ace_line\">\n<pre class=\"lang:default decode:true\">print(True if 0 &gt;= 0 else False)<\/pre>\n<p>outputs <code>True<\/code>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p>4. A <b>list comprehension<\/b> becomes a <b>generator<\/b> when used inside <b>parentheses<\/b> (used inside brackets, it produces a regular list). For example:<\/p>\n<div class=\"ace-tm\">\n<div class=\"ace_static_highlight\">\n<pre class=\"lang:default decode:true\">for x in (el * 2 for el in range(5)):\r\n  print(x)<\/pre>\n<\/div>\n<\/div>\n<p>outputs <code>02468<\/code>.<\/p>\n<p>or<\/p>\n<pre class=\"lang:default decode:true\">def powers_of_2(n):\r\n    power = 1\r\n    for i in range(n):\r\n        yield power\r\n        power *= 2\r\n\r\n\r\nt = [x for x in powers_of_2(5)]\r\nprint(t)<\/pre>\n<p><code>[1, 2, 4, 8, 16]<\/code><\/p>\n<p>&nbsp;<\/p>\n<p>More examples list comprehensions:<\/p>\n<pre class=\"lang:default decode:true \">list_1 = []\r\n\r\nfor ex in range(6):\r\n    list_1.append(10 ** ex)\r\n\r\nlist_2 = [10 ** ex for ex in range(6)]\r\n\r\nprint(list_1)\r\nprint(list_2)<\/pre>\n<p><code>[1, 10, 100, 1000, 10000, 100000]<\/code><\/p>\n<p><code>[1, 10, 100, 1000, 10000, 100000]<\/code><\/p>\n<p>&nbsp;<\/p>\n<pre class=\"lang:default decode:true\">the_list = []\r\nfor x in range(10):\r\n    the_list.append(1 if x % 2 == 0 else 0)\r\n\r\nprint(the_list)\r\n<\/pre>\n<p><code>[1, 0,<\/code><code> 1, 0, 1, 0, 1, 0, 1, 0]<\/code><\/p>\n<p>&nbsp;<\/p>\n<p>5. List comprehensions vs. generators<\/p>\n<p>Just one change can <strong>turn any list comprehension into a generator<\/strong>. It&#8217;s the <strong>parentheses<\/strong>. The brackets make a comprehension, the parentheses make a generator.<\/p>\n<pre class=\"lang:default decode:true\">the_list = [1 if x % 2 == 0 else 0 for x in range(10)]\r\nthe_generator = (1 if x % 2 == 0 else 0 for x in range(10))\r\n\r\nfor v in the_list:\r\n    print(v, end=\" \")\r\nprint()\r\n\r\nfor v in the_generator:\r\n    print(v, end=\" \")\r\nprint()\r\n\r\nprint(len(the_list))\r\nprint(len(the_generator))<\/pre>\n<p><code>1 0 1 0 1 0 1 0 1 0<\/code><\/p>\n<p><code>1 0 1 0 1 0 1 0 1 0<\/code><\/p>\n<p><code>10<\/code><\/p>\n<p><code>Traceback (most recent call last):<\/code><\/p>\n<p><code>File \"main.py\", line 15, in &lt;module&gt;<\/code><\/p>\n<p><code>print (len(the_generator))<\/code><\/p>\n<p><code>TypeError: object of type 'generator' has no len()<\/code><\/p>\n<p>You can&#8217;t use the len() function on the generator.<\/p>\n<p>&nbsp;<\/p>\n<p>6. The <strong><span style=\"font-family: Courier New;\">list()<\/span><\/strong> function can transform a series of subsequent generator invocations into a real list:<\/p>\n<pre class=\"lang:default decode:true\">def powers_of_2(n):\r\n    power = 1\r\n    for i in range(n):\r\n        yield power\r\n        power *= 2\r\n\r\nt = list(powers_of_2(3))\r\nprint(t)<\/pre>\n<p><code>[1, 2, 4]<\/code><\/p>\n<p>&nbsp;<\/p>\n<p>7. The <code><strong>in<\/strong><\/code> operator allows you to use a generator, too.<\/p>\n<pre class=\"lang:default decode:true\">def powers_of_2(n):\r\n    power = 1\r\n    for i in range(n):\r\n        yield power\r\n        power *= 2\r\n\r\n\r\nfor i in range(20):\r\n    if i in powers_of_2(4):\r\n        print(i)<\/pre>\n<p><code>1<\/code><br \/>\n<code>2<\/code><br \/>\n<code>4<\/code><br \/>\n<code>8<\/code><\/p>\n<p>&nbsp;<\/p>\n<p>8. <strong>Fibonacci number generator <\/strong>looks much better than the objective version based on the direct iterator protocol implementation.<\/p>\n<pre class=\"lang:default decode:true \">def fibonacci(n):\r\n    p = pp = 1\r\n    for i in range(n):\r\n        if i in [0, 1]:\r\n            yield 1\r\n        else:\r\n            n = p + pp\r\n            pp, p = p, n\r\n            yield n\r\n\r\nfibs = list(fibonacci(10))\r\nprint(fibs)<\/pre>\n<p><code>[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]<\/code><\/p>\n<p>&nbsp;<\/p>\n<p>9. A <b>lambda <\/b>is a function without a name (you can also call it <strong>an anonymous function<\/strong>). The declaration of the <strong><code>lambda<\/code> <\/strong>function doesn&#8217;t resemble a normal function declaration in any way:<\/p>\n<pre class=\"lang:default decode:true\">lambda parameters: expression<\/pre>\n<p><em>Example 1.<\/em><\/p>\n<div class=\"ace-tm\">\n<div class=\"ace_static_highlight\">\n<pre class=\"lang:default decode:true\">def foo(x, f):\r\n  return f(x)\r\n\r\nprint(foo(9, lambda x: x ** 0.5))<\/pre>\n<p>outputs <code>3.0<\/code>.<\/p>\n<p><em>Example 2.<\/em><\/p>\n<\/div>\n<\/div>\n<pre class=\"lang:default decode:true\">two = lambda: 2\r\nsqr = lambda x: x * x\r\npwr = lambda x, y: x ** y\r\n\r\nfor a in range(-2, 3):\r\n    print(sqr(a), end=\" \")\r\n    print(pwr(a, two()))<\/pre>\n<p><code>4 4<\/code><br \/>\n<code>1 1<\/code><br \/>\n<code>0 0<\/code><br \/>\n<code>1 1<\/code><br \/>\n<code>4 4<\/code><\/p>\n<p><em>Example 3.<\/em><\/p>\n<pre class=\"lang:default decode:true\">def print_function(args, fun):\r\n    for x in args:\r\n        print('f(', x,')=', fun(x), sep='')\r\n\r\ndef poly(x):\r\n    return 2 * x**2 - 4 * x + 2\r\n\r\nprint_function([x for x in range(-2, 3)], poly)<\/pre>\n<p><code>f(-2)=18<\/code><\/p>\n<p><code>f(-1)=8<\/code><\/p>\n<p><code>f(0)=2<\/code><\/p>\n<p><code>f(1)=0<\/code><\/p>\n<p><code>f(2)=2<\/code><\/p>\n<pre class=\"lang:default decode:true \">def print_function(args, fun):\r\n    for x in args:\r\n        print('f(', x,')=', fun(x), sep='')\r\n\r\nprint_function([x for x in range(-2, 3)], lambda x: 2 * x**2 - 4 * x + 2)<\/pre>\n<p>&nbsp;<\/p>\n<p><a href=\"https:\/\/www.python.org\/dev\/peps\/pep-0008\/#programming-recommendations\" target=\"_blank\" rel=\"noopener\">PEP 8<\/a>, the Style Guide for Python Code, recommends that <b>lambdas should not be assigned to variables, but rather they should be defined as functions<\/b>.<\/p>\n<p>This means that it is better to use a <code>def<\/code> statement, and avoid using an assignment statement that binds a lambda expression to an identifer. Analyze the code below:<\/p>\n<pre class=\"lang:default decode:true \"># Not recommended:\r\nf = lambda x: 3*x\r\n\r\n# Recommended:\r\ndef f(x): return 3*x\r\n\r\n\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>10. The <code><strong>map(fun, list)<\/strong><\/code> function creates a <b>copy<\/b> of a <code>list<\/code> argument, and applies the <code>fun<\/code> function to all of its elements, returning a <b>generator<\/b> that provides the new list content element by element.<\/p>\n<p>&nbsp;<\/p>\n<p><em>Example 1.<\/em><\/p>\n<div class=\"ace-tm\">\n<div class=\"ace_static_highlight\">\n<pre class=\"lang:default decode:true\">short_list = ['mython', 'python', 'fell', 'on', 'the', 'floor']\r\nnew_list = list(map(lambda s: s.title(), short_list))\r\nprint(new_list)<\/pre>\n<p>outputs<\/p>\n<p><code>['Mython', 'Python', 'Fell', 'On', 'The', 'Floor']<\/code>.<\/p>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p><em>Example 2.<\/em><\/p>\n<pre class=\"lang:default decode:true\">list_1 = [x for x in range(5)]\r\nprint(list_1)\r\n\r\nlist_2 = list(map(lambda x: 2 ** x, list_1))\r\nprint(list_2)\r\n\r\nfor x in map(lambda x: x * x, list_2):\r\n    print(x, end=' ')\r\nprint()<\/pre>\n<p><code>[0, 1, 2, 3, 4]<\/code><\/p>\n<p><code>[1, 2, 4, 8, 16]<\/code><\/p>\n<p><code>1 4 16 64 256<\/code><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>11. The <strong><code>filter(fun, list)<\/code><\/strong> function creates a <b>copy<\/b> of those <code>list<\/code> elements, which cause the <code>fun<\/code> function to return <code>True<\/code>. The function&#8217;s result is a <b>generator<\/b> providing the new list content element by element.<\/p>\n<p><em>Example 1.<\/em><\/p>\n<p>The <code class=\"w3-codespan\">isinstance()<\/code> function returns <code class=\"w3-codespan\">True<\/code> if the specified object is of the specified type, otherwise <code class=\"w3-codespan\">False<\/code>.<\/p>\n<div class=\"ace-tm\">\n<div class=\"ace_static_highlight\">\n<pre class=\"lang:default decode:true\">short_list = [1, \"Python\", -1, \"Monty\"]\r\nnew_list = list(filter(lambda s: isinstance(s, str), short_list))\r\nprint(new_list)<\/pre>\n<p>outputs<\/p>\n<p><code>['Python', 'Monty']<\/code>.<\/p>\n<p>&nbsp;<\/p>\n<p><em>Example 2.<\/em><\/p>\n<pre class=\"lang:default decode:true \">from random import seed, randint\r\n\r\nseed()\r\ndata = [randint(-5,15) for x in range(5)]\r\nfiltered = list(filter(lambda x: x &gt; 0 and x % 2 == 0, data))\r\n\r\nprint(data)\r\nprint(filtered)<\/pre>\n<p><code>[1, 8, 2, 7, -2]<\/code><\/p>\n<p><code>[8, 2]<\/code><\/p>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p>12. A <strong>closure<\/strong> is a technique which allows the <b>storing of values<\/b> in spite of the fact that the <b>context<\/b> in which they have been created <b>does not exist anymore<\/b>.<\/p>\n<p><em>Example 3:<\/em><\/p>\n<pre class=\"lang:default decode:true \">def outer(par):\r\n    loc = par\r\n\r\n    def inner():\r\n        return loc\r\n    return inner\r\n\r\n\r\nvar = 1\r\nfun = outer(var)\r\nprint(fun())\r\n<\/pre>\n<p><code>1<\/code><\/p>\n<p><em>Example 4:<\/em><\/p>\n<pre class=\"lang:default decode:true \">def make_closure(par):\r\n    loc = par\r\n\r\n    def power(p):\r\n        return p ** loc\r\n    return power\r\n\r\nfsqr = make_closure(2)   # loc = 2\r\nfcub = make_closure(3)   # loc = 3\r\n\r\nfor i in range(5):\r\n    print(i, fsqr(i), fcub(i))  # p = i<\/pre>\n<p>Note:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>the first closure obtained from <code>make_closure()<\/code> defines a tool <strong>squaring<\/strong> its argument (<code>fsqr<\/code>);<\/li>\n<li>the second one is designed to <strong>cube<\/strong> the argument (<code>fcub<\/code>).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>This is why the code produces the following output:<\/p>\n<p><code>0 0 0<\/code><\/p>\n<p><code>1 1 1<\/code><\/p>\n<p><code>2 4 8<\/code><\/p>\n<p><code>3 9 27<\/code><\/p>\n<p><code>4 16 64<\/code><\/p>\n<p>&nbsp;<\/p>\n<p><em>Example 5:<\/em><\/p>\n<div class=\"ace-tm\">\n<div class=\"ace_static_highlight\">\n<pre class=\"lang:default decode:true\">def tag(tg):\r\n  tg2 = tg\r\n  tg2 = tg[0] + '\/' + tg[1:]\r\n\r\n  def inner(str):\r\n    return tg + str + tg2\r\n  return inner\r\n\r\nb_tag = tag('&lt;b&gt;')\r\nprint(b_tag('Monty Python'))<\/pre>\n<\/div>\n<\/div>\n<p>outputs<\/p>\n<p><code>&lt;b&gt;Monty Python&lt;\/b&gt;<\/code><\/p>\n<p>&nbsp;<\/p>\n<p><em>Exercise 1<\/em><\/p>\n<p>What is the expected output of the following code?<\/p>\n<pre class=\"lang:default decode:true\">class Vowels:\r\n    def __init__(self):\r\n        self.vow = \"aeiouy \"  # Yes, we know that y is not always considered a vowel.\r\n        self.pos = 0\r\n\r\n    def __iter__(self):\r\n        return self\r\n\r\n    def __next__(self):\r\n        if self.pos == len(self.vow):\r\n            raise StopIteration\r\n        self.pos += 1\r\n        return self.vow[self.pos - 1]\r\n\r\nvowels = Vowels()\r\nfor v in vowels:\r\n    print(v, end=' ')<\/pre>\n<p><code>a e i o u y<\/code><\/p>\n<p>&nbsp;<\/p>\n<p><em>Exercise 2<\/em><\/p>\n<p>Write a lambda function, setting the least significant bit of its integer argument, and apply it to the <code>map()<\/code> function to produce the string<code> 1 3 3 5<\/code> on the console.<\/p>\n<pre class=\"lang:default decode:true\">any_list = [1, 2, 3, 4]\r\neven_list = # Complete the line here.\r\nprint(even_list)<\/pre>\n<p>Lambda:<\/p>\n<pre class=\"lang:default decode:true \">list(map(lambda n: n | 1, any_list))<\/pre>\n<p>&nbsp;<\/p>\n<p><em>Exercise 3<\/em><\/p>\n<p>What is the expected output of the following code?<\/p>\n<pre class=\"lang:default decode:true \">def replace_spaces(replacement='*'):\r\n    def new_replacement(text):\r\n        return text.replace(' ', replacement)\r\n    return new_replacement\r\n\r\n\r\nstars = replace_spaces()\r\nprint(stars(\"And Now for Something Completely Different\"))<\/pre>\n<p><code>And*Now*for*Something*Completely*Different<\/code><\/p>\n<p>&nbsp;<\/p>\n<p>Ex. 4<\/p>\n<p>What is the expected output of the following snippet ?<\/p>\n<pre class=\"lang:default decode:true \">    x = 5\/\/2\r\n    func = lambda x:+3\r\n    print(func(x))<\/pre>\n<p>Explanation:<\/p>\n<p>Function <code>func <\/code>is defined as a <strong>lambda <\/strong>function. The variable <code>x<\/code> in the definition of the <strong>lambda <\/strong>function is a local variable and has no scope outside of the lambda function. The lambda function does not even use this local variable and simply return <code>3<\/code>.<\/p>\n<p>So calling <code>func(x)<\/code>\u00a0 for any value of <code>x<\/code> will always return 3.<\/p>\n<p>Try it yourself:<\/p>\n<pre class=\"lang:default decode:true \">    x = 5\/\/2              # x = 2 but that does not really matter\r\n    func = lambda x:+3\r\n    print(func(x))        # 3<\/pre>\n<p>&nbsp;<\/p>\n<p>Ex.5<\/p>\n<p>What is the expected output of the following code snippet ?<\/p>\n<pre class=\"lang:default decode:true \">    def f(x):\r\n        def g(y):\r\n            return x * y\r\n        return g\r\n     \r\n    k = f(4)\r\n    print(k(4))<\/pre>\n<p>Explanation:<\/p>\n<p>The above function is a <strong>closure<\/strong>.<\/p>\n<p>We have a closure in Python when\u00a0 :<\/p>\n<p>&#8211; there is a nested function (function inside a function).<\/p>\n<p>&#8211; the nested function refers to a value defined in the enclosing function.<\/p>\n<p>&#8211; the enclosing function returns the nested function.<\/p>\n<p>Here we have function <code>g()<\/code> nested inside function <code>f()<\/code>. Function <code>f()<\/code> returns function <code>g()<\/code>.<\/p>\n<p>So, <code>f(4)<\/code> returns function <code>g()<\/code> that itself will return <code>4*y<\/code>\u00a0 (replace <code>x<\/code> with <code>4<\/code> in the function definition).<\/p>\n<p>And finally <code>k(4)<\/code> will return <code>4*4<\/code> , i.e. <code>16<\/code>.<\/p>\n<p>&nbsp;<\/p>\n<p>Ex.6<\/p>\n<p>What is the expected output of the following snippet ?<\/p>\n<pre class=\"lang:default decode:true \">    from math import ceil\r\n     \r\n    def func(g,x):\r\n        return g(x) + 1\r\n        \r\n    print(func(lambda x: ceil(x),3.2))<\/pre>\n<p><em>Explanation:<\/em><\/p>\n<p>Here a <strong>lambda <\/strong>function is being used as a parameter of function <code>func()<\/code>. This lambda function returns <code>ceil(x)<\/code> where <code>ceil()<\/code> is a function from the <code>math <\/code>module that returns the smallest integer greater than or equal to variable <code>x<\/code> .<\/p>\n<p>So, <code>func(lambda x: ceil(x),3.2) <\/code> will return <code>ceil(3.2) + 1<\/code> i.e : <code>4 + 1<\/code> &#8211;&gt; <code>5<\/code><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A Python generator is a piece of specialized code able to produce a series of values, and to control the iteration process. This is why generators are very often called iterators, and although some may find a very subtle distinction between these two, we&#8217;ll treat them as one.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[100],"tags":[],"_links":{"self":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts\/6085"}],"collection":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/comments?post=6085"}],"version-history":[{"count":24,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts\/6085\/revisions"}],"predecessor-version":[{"id":6278,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts\/6085\/revisions\/6278"}],"wp:attachment":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/media?parent=6085"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/categories?post=6085"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/tags?post=6085"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}