{"id":1925,"date":"2019-06-14T21:27:36","date_gmt":"2019-06-14T21:27:36","guid":{"rendered":"http:\/\/wiki.thomasandsofia.com\/?p=1925"},"modified":"2019-06-14T22:07:07","modified_gmt":"2019-06-14T22:07:07","slug":"section-13-python-generators","status":"publish","type":"post","link":"https:\/\/wiki.thomasandsofia.com\/?p=1925","title":{"rendered":"Section 13: Python Generators"},"content":{"rendered":"<p><a href=\"http:\/\/wiki.thomasandsofia.com\/?p=1919\">&lt; Section 12<\/a> | Section 14<\/p>\n<h1>Generators with Python<\/h1>\n<p><a href=\"https:\/\/www.udemy.com\/complete-python-bootcamp\/learn\/lecture\/9523120#questions\" target=\"_blank\" rel=\"noopener\">https:\/\/www.udemy.com\/complete-python-bootcamp\/learn\/lecture\/9523120#questions<\/a><\/p>\n<p>Generator functions all us to write a function that can send back a value and then later resume to pick up where it left off.<\/p>\n<ul>\n<li>These allow us to generate a sequence of values over time.<\/li>\n<li>The main difference in syntax will be the user of a yield statement.<\/li>\n<li>When a generator function is compiled it become s an object that supports an iteration protocol.<\/li>\n<li>This means when they are called in uyour code, the don&#8217;t actually return a value and then exit.<\/li>\n<li>Generator functions will automatically suspend and resume their execution and state around the last point of value generation<\/li>\n<li>The advantage is that instead of having to compute an entire series of values up front and hold it in memory, the generator computes one value then waits until the next value is called for.\n<ul>\n<li>Think of the &#8216;range&#8217; function.<\/li>\n<\/ul>\n<\/li>\n<li>If the user actually wanted all of the values, they could use the list() function.\n<ul>\n<li>Example: list(range(0,10))<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Standard &#8216;list&#8217; style function example:<\/p>\n<pre>def cubit(n):\r\n    result = []\r\n    for x in range(n):\r\n        result.append(x**3)\r\n    return result\r\ncubit(4)<\/pre>\n<p>[0, 1, 8, 27]<\/p>\n<p>For this function to work, it must store the entire list in memory before sending any data back.<\/p>\n<p>This example shows how to iterate through the result, but every value is already stored in memory:<\/p>\n<pre>for x in cubit(4):\r\n    print(x)<\/pre>\n<p>0<br \/>\n1<br \/>\n8<br \/>\n27<\/p>\n<h2>yeild<\/h2>\n<p>Use the yield command to return values as you iterate through them without having to store all of the values in a list:<\/p>\n<pre>def cubit(n):\r\n    for x in range(n):\r\n        yield x**3\r\nfor x in cubit(4):\r\n    print(x)<\/pre>\n<p>0<br \/>\n1<br \/>\n8<br \/>\n27<\/p>\n<h3>Generate Fibonacci sequence<\/h3>\n<pre>def fibonacci(n):\r\n    i = 0\r\n    j = 1\r\n    for x in range(n):\r\n        yield j\r\n        i, j = j, i + j\r\nfor x in fibonacci(7):\r\n    print(x)<\/pre>\n<p>1<br \/>\n1<br \/>\n2<br \/>\n3<br \/>\n5<br \/>\n8<br \/>\n13<\/p>\n<h2>How Generators Word<\/h2>\n<p>The key to making generators work are the &#8216;Next&#8217; function and the &#8216;ittr&#8217; function:<\/p>\n<h3>next() function<\/h3>\n<p>Before we start:<\/p>\n<pre>def counter():\r\n    for x in range(3):\r\n        yield x\r\nfor num in counter():\r\n    print(num)<\/pre>\n<p>0<br \/>\n1<br \/>\n2<\/p>\n<p>Now try this:<\/p>\n<pre>def counter():\r\n    for x in range(3):\r\n        yield x\r\ng = counter()\r\ng<\/pre>\n<p>&lt;generator object counter at 0x00000179756E5570&gt;<\/p>\n<pre>print(next(g))<\/pre>\n<p>0<\/p>\n<pre>print(next(g))<\/pre>\n<p>1<\/p>\n<pre>print(next(g))<\/pre>\n<p>2<\/p>\n<pre>print(next(g))<\/pre>\n<p><span class=\"ansi-red-intense-fg ansi-bold\">&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/span> <span class=\"ansi-red-intense-fg ansi-bold\">StopIteration<\/span> Traceback (most recent call last) <span class=\"ansi-green-intense-fg ansi-bold\">&lt;ipython-input-25-1dfb29d6357e&gt;<\/span> in <span class=\"ansi-cyan-fg\">&lt;module&gt;<\/span> <span class=\"ansi-green-intense-fg ansi-bold\">&#8212;-&gt; 1<\/span> print<span class=\"ansi-yellow-intense-fg ansi-bold\">(<\/span>next<span class=\"ansi-yellow-intense-fg ansi-bold\">(<\/span>g<span class=\"ansi-yellow-intense-fg ansi-bold\">)<\/span><span class=\"ansi-yellow-intense-fg ansi-bold\">)<\/span> <span class=\"ansi-red-intense-fg ansi-bold\">StopIteration<\/span>:<\/p>\n<p><strong>Note! This is the same thing a for loop does, except it catches the error and stops processing!<\/strong><\/p>\n<pre>g = counter()\r\nwhile True:\r\n    try:\r\n        print(next(g))\r\n    except:\r\n        break<\/pre>\n<p>0<br \/>\n1<br \/>\n2<\/p>\n<h3>iter() function<\/h3>\n<p>&amp;nbsp<\/p>\n<pre>s = 'hello'\r\nfor x in s:\r\n    print(x)<\/pre>\n<p>h<br \/>\ne<br \/>\nl<br \/>\nl<br \/>\no<\/p>\n<pre>s = 'hello'\r\nnext(s)<\/pre>\n<p>TypeError: &#8216;str&#8217; object is not an iterator<\/p>\n<pre>s = 'hello'\r\ns_iter = iter(s)\r\nnext(s_iter)<\/pre>\n<p>h<\/p>\n<pre>next(s_iter)<\/pre>\n<p>e<\/p>\n<p>and so on&#8230;<\/p>\n<h1>Generator Homework Overview<\/h1>\n<p><a href=\"https:\/\/www.udemy.com\/complete-python-bootcamp\/learn\/lecture\/9523126#questions\" target=\"_blank\" rel=\"noopener\">https:\/\/www.udemy.com\/complete-python-bootcamp\/learn\/lecture\/9523126#questions<\/a><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&lt; Section 12 | Section 14 Generators with Python https:\/\/www.udemy.com\/complete-python-bootcamp\/learn\/lecture\/9523120#questions Generator functions all us to write a function that can send back a value and then later resume to pick up where it left off. These allow us to generate a sequence of values over time. The main difference in syntax will be the user ..<\/p>\n<div class=\"clear-fix\"><\/div>\n<p><a href=\"https:\/\/wiki.thomasandsofia.com\/?p=1925\" title=\"read more...\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[44],"tags":[],"class_list":["post-1925","post","type-post","status-publish","format-standard","hentry","category-python-bootcamp-0-to-hero"],"_links":{"self":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts\/1925","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1925"}],"version-history":[{"count":3,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts\/1925\/revisions"}],"predecessor-version":[{"id":1928,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts\/1925\/revisions\/1928"}],"wp:attachment":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1925"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1925"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1925"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}