|
| 1 | +{ |
| 2 | + "cells": [ |
| 3 | + { |
| 4 | + "cell_type": "markdown", |
| 5 | + "metadata": {}, |
| 6 | + "source": [ |
| 7 | + "Lesson 9 \n", |
| 8 | + "Advanced Topics in Python\n", |
| 9 | + "\n", |
| 10 | + "Iterators and Generators\n", |
| 11 | + "\n", |
| 12 | + "Iterables are objects that can return one of their elements at a time, such as a list. Many of the built-in functions we’ve used so far, like 'enumerate,' return an iterator.\n", |
| 13 | + "\n", |
| 14 | + "An iterator is an object that represents a stream of data. This is different from a list, which is also an iterable, but is not an iterator because it is not a stream of data.\n", |
| 15 | + "\n", |
| 16 | + "Generators are a simple way to create iterators using functions. You can also define iterators using classes, which you can read more about here.\n", |
| 17 | + "\n", |
| 18 | + "Generators are a lazy way to build iterables. They are useful when the fully realized list would not fit in memory, or when the cost to calculate each list element is high and you want to do it as late as possible. But they can only be iterated over once.\n" |
| 19 | + ] |
| 20 | + }, |
| 21 | + { |
| 22 | + "cell_type": "markdown", |
| 23 | + "metadata": {}, |
| 24 | + "source": [ |
| 25 | + "### Quiz 1: Implement `my_enumerate`\n", |
| 26 | + "\n", |
| 27 | + "Write your own generator function `my_enumerate` that works like the built-in function `enumerate`.\n", |
| 28 | + "\n", |
| 29 | + "Calling your function like this:\n", |
| 30 | + "\n", |
| 31 | + "```python\n", |
| 32 | + "lessons = [\"Why Python Programming\", \"Data Types and Operators\", \"Control Flow\", \"Functions\", \"Scripting\"]\n", |
| 33 | + "\n", |
| 34 | + "for i, lesson in my_enumerate(lessons, 1):\n", |
| 35 | + " print(\"Lesson {}: {}\".format(i, lesson))\n", |
| 36 | + "```\n", |
| 37 | + "\n", |
| 38 | + "should output:\n", |
| 39 | + "\n", |
| 40 | + "```txt\n", |
| 41 | + "Lesson 1: Why Python Programming\n", |
| 42 | + "Lesson 2: Data Types and Operators\n", |
| 43 | + "Lesson 3: Control Flow\n", |
| 44 | + "Lesson 4: Functions\n", |
| 45 | + "Lesson 5: Scripting\n", |
| 46 | + "```" |
| 47 | + ] |
| 48 | + }, |
| 49 | + { |
| 50 | + "cell_type": "code", |
| 51 | + "execution_count": 3, |
| 52 | + "metadata": {}, |
| 53 | + "outputs": [ |
| 54 | + { |
| 55 | + "name": "stdout", |
| 56 | + "output_type": "stream", |
| 57 | + "text": [ |
| 58 | + "Lesson 1: Why Python Programming\n", |
| 59 | + "Lesson 2: Data Types and Operators\n", |
| 60 | + "Lesson 3: Control Flow\n", |
| 61 | + "Lesson 4: Functions\n", |
| 62 | + "Lesson 5: Scripting\n" |
| 63 | + ] |
| 64 | + } |
| 65 | + ], |
| 66 | + "source": [ |
| 67 | + "lessons = [\"Why Python Programming\", \"Data Types and Operators\", \"Control Flow\", \"Functions\", \"Scripting\"]\n", |
| 68 | + "\n", |
| 69 | + "# this is a function that works like built-in enumerate\n", |
| 70 | + "def my_enumerate(iterable, start=0):\n", |
| 71 | + " \"\"\"\n", |
| 72 | + " Args:\n", |
| 73 | + " (object) iterable - the iterable object\n", |
| 74 | + " (int) start - the start index\n", |
| 75 | + " \"\"\"\n", |
| 76 | + " count = start\n", |
| 77 | + " for element in iterable: \n", |
| 78 | + " # Yeild is used like return but it returns generator \n", |
| 79 | + " yield count, element \n", |
| 80 | + " count = count + 1\n", |
| 81 | + " \n", |
| 82 | + "#Code to test your my_enumerate function\n", |
| 83 | + "for i, lesson in my_enumerate(lessons, 1):\n", |
| 84 | + " print(\"Lesson {}: {}\".format(i, lesson))" |
| 85 | + ] |
| 86 | + }, |
| 87 | + { |
| 88 | + "cell_type": "markdown", |
| 89 | + "metadata": {}, |
| 90 | + "source": [ |
| 91 | + "### Quiz 2: Chunker\n", |
| 92 | + "\n", |
| 93 | + "If you have an iterable that is too large to fit in memory in full (e.g., when dealing with large files), being able to take and use chunks of it at a time can be very valuable.\n", |
| 94 | + "\n", |
| 95 | + "Implement a generator function, `chunker`, that takes in an iterable and yields a chunk of a specified size at a time.\n", |
| 96 | + "\n", |
| 97 | + "Calling the function like this:\n", |
| 98 | + "\n", |
| 99 | + "```python\n", |
| 100 | + "for chunk in chunker(range(25), 4):\n", |
| 101 | + " print(list(chunk))\n", |
| 102 | + "```\n", |
| 103 | + "\n", |
| 104 | + "should output:\n", |
| 105 | + "\n", |
| 106 | + "```txt\n", |
| 107 | + "[0, 1, 2, 3]\n", |
| 108 | + "[4, 5, 6, 7]\n", |
| 109 | + "[8, 9, 10, 11]\n", |
| 110 | + "[12, 13, 14, 15]\n", |
| 111 | + "[16, 17, 18, 19]\n", |
| 112 | + "[20, 21, 22, 23]\n", |
| 113 | + "[24]\n", |
| 114 | + "```" |
| 115 | + ] |
| 116 | + }, |
| 117 | + { |
| 118 | + "cell_type": "code", |
| 119 | + "execution_count": 5, |
| 120 | + "metadata": {}, |
| 121 | + "outputs": [ |
| 122 | + { |
| 123 | + "name": "stdout", |
| 124 | + "output_type": "stream", |
| 125 | + "text": [ |
| 126 | + "[0, 1, 2, 3]\n", |
| 127 | + "[4, 5, 6, 7]\n", |
| 128 | + "[8, 9, 10, 11]\n", |
| 129 | + "[12, 13, 14, 15]\n", |
| 130 | + "[16, 17, 18, 19]\n", |
| 131 | + "[20, 21, 22, 23]\n", |
| 132 | + "[24]\n" |
| 133 | + ] |
| 134 | + } |
| 135 | + ], |
| 136 | + "source": [ |
| 137 | + "def chunker(iterable, size):\n", |
| 138 | + " \"\"\"\n", |
| 139 | + " Args:\n", |
| 140 | + " (object) iterable - the iterable object\n", |
| 141 | + " (int) size - the start index\n", |
| 142 | + " \"\"\"\n", |
| 143 | + " for i in range(0, len(iterable), size):\n", |
| 144 | + " yield iterable[i:i + size]\n", |
| 145 | + "\n", |
| 146 | + "# Code to test your chunker function\n", |
| 147 | + "for chunk in chunker(range(25), 4):\n", |
| 148 | + " print(list(chunk))" |
| 149 | + ] |
| 150 | + }, |
| 151 | + { |
| 152 | + "cell_type": "markdown", |
| 153 | + "metadata": {}, |
| 154 | + "source": [ |
| 155 | + "Generator Expressions\n", |
| 156 | + "\n", |
| 157 | + "Here's a cool concept that combines generators and list comprehensions! You can actually create a generator in the same way you'd normally write a list comprehension, except with parentheses instead of square brackets. For example:\n", |
| 158 | + "This can help you save time and create efficient code!" |
| 159 | + ] |
| 160 | + }, |
| 161 | + { |
| 162 | + "cell_type": "code", |
| 163 | + "execution_count": null, |
| 164 | + "metadata": {}, |
| 165 | + "outputs": [], |
| 166 | + "source": [ |
| 167 | + "sq_list = [x**2 for x in range(10)] # this produces a list of squares\n", |
| 168 | + "sq_iterator = (x**2 for x in range(10)) # this produces an iterator of squares" |
| 169 | + ] |
| 170 | + } |
| 171 | + ], |
| 172 | + "metadata": { |
| 173 | + "kernelspec": { |
| 174 | + "display_name": "Python 3", |
| 175 | + "language": "python", |
| 176 | + "name": "python3" |
| 177 | + }, |
| 178 | + "language_info": { |
| 179 | + "codemirror_mode": { |
| 180 | + "name": "ipython", |
| 181 | + "version": 3 |
| 182 | + }, |
| 183 | + "file_extension": ".py", |
| 184 | + "mimetype": "text/x-python", |
| 185 | + "name": "python", |
| 186 | + "nbconvert_exporter": "python", |
| 187 | + "pygments_lexer": "ipython3", |
| 188 | + "version": "3.11.0" |
| 189 | + }, |
| 190 | + "orig_nbformat": 4 |
| 191 | + }, |
| 192 | + "nbformat": 4, |
| 193 | + "nbformat_minor": 2 |
| 194 | +} |
0 commit comments