{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import time" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Introduction to Python \n", "\n", "# [Comprehensions](https://python-3-patterns-idioms-test.readthedocs.io/en/latest/Comprehensions.html) and [Generators](https://www.programiz.com/python-programming/generator)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## [Comprehensions](https://towardsdatascience.com/list-comprehensions-in-python-28d54c9286ca):" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python offers some nice \"synctatic sugar\" constructions. They allow the creation of sequences in a clear in concise way \n", "They are: \n", "\n", "- List comprehension\n", "- Set comprehension\n", "- Dict comprehension" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1) List Comprehensions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "List comprehensions returns a list filled with elements derived from another sequence ot iterable, being modified or not. A common use is to build a new list where each element is the result of some expression applied to the original, or to build a sequence where the elements satisfy some conditions \n", "\n", "The patterns are: \n", "\n", " [ for in ]\n", " [ for in if ]\n", " [ if else for in ]\n", " [ if else for in if ]\n", " \n", "\n", "See the examples below: " ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "cubes = []\n", "for number in range(10):\n", " cubes.append(number**3)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0, 1, 8, 27, 64, 125, 216, 343, 512, 729]\n" ] } ], "source": [ "print(cubes)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### We can rewrite it in a more concise way using list comprehension: " ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "cubes2 = [number**3 for number in range(10)]" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0, 1, 8, 27, 64, 125, 216, 343, 512, 729]\n" ] } ], "source": [ "print(cubes2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Another example of the use of list comprehensions \n", "Let's sum the square of the divisors of 3 and 5 below 1000: " ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "155638903886\n", "CPU times: user 2.72 ms, sys: 0 ns, total: 2.72 ms\n", "Wall time: 2.72 ms\n" ] } ], "source": [ "%%time\n", "\n", "my_list = []\n", "for x in range(10001):\n", " if x%5 == 0 or x%3 == 0:\n", " my_list.append(x**2)\n", "print(sum(my_list))" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "155638903886\n", "CPU times: user 1.72 ms, sys: 326 µs, total: 2.04 ms\n", "Wall time: 2.05 ms\n" ] } ], "source": [ "%%time\n", "\n", "my_new_list = [x**2 for x in range(10001) if x%5 == 0 or x%3 == 0]\n", "print(sum(my_new_list))" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "print(type(my_new_list))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### More examples:\n", "\n", "+ #### Modifying a sequence " ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "range(0, 11)" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sequence = range(11)\n", "sequence" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(sequence)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 4, 16, 36, 64, 100]" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[element**2 for element in sequence if element%2 == 0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "+ #### More than one variable" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[13, 14, 11]" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[x + y for x,y in [(9,4),(8,6),(2,9)]]" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(4, 9), (6, 8), (9, 2)]" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[(y,x) for x,y in [(9,4),(8,6),(2,9)]]" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[2, 2, 4]" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[x if x%2==0 else y for x,y in [(1,2),(2,3),(4,5)] if isinstance(x,int) or isinstance(y,float)]" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'sOMe oDd STRiNG'" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def swapcase(string):\n", " swapped = \"\".join([x.upper() if x.islower() else x.lower() for x in string])\n", " return swapped\n", "\n", "swapcase(\"SomE OdD strIng\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "+ #### No variables" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[5, 5, 5, 5]\n", "CPU times: user 82 µs, sys: 22 µs, total: 104 µs\n", "Wall time: 125 µs\n" ] } ], "source": [ "%%time\n", "\n", "print([3+2 for numero in range(4)])" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[5, 5, 5, 5]\n", "CPU times: user 67 µs, sys: 0 ns, total: 67 µs\n", "Wall time: 71 µs\n" ] } ], "source": [ "%%time\n", "\n", "print(4 * [5])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "+ #### Filtering by type" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 9, 0, 4]\n" ] } ], "source": [ "my_list = [1, \"4\", 9, \"a\", 0, 4]\n", "test_type = [elem for elem in my_list if isinstance(elem, int)]\n", "print(test_type)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "+ #### Filtering by type, two conditions: " ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 4, 9, 0, 4]\n" ] } ], "source": [ "my_list = [1, \"4\", 9, \"a\", 0, 4]\n", "test_type = [int(i) for i in my_list if isinstance(i, int) or (isinstance(i, str) and (i.isnumeric()))]\n", "print(test_type)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "+ #### Multiple loops " ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[(1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5)]\n", "CPU times: user 106 µs, sys: 0 ns, total: 106 µs\n", "Wall time: 111 µs\n" ] } ], "source": [ "%%time\n", "\n", "points = []\n", "for x in [1,2,3]:\n", " for y in [3,4,5]:\n", " if x != y:\n", " points.append((x,y))\n", " \n", "print(points)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[(1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5)]\n", "CPU times: user 115 µs, sys: 0 ns, total: 115 µs\n", "Wall time: 120 µs\n" ] } ], "source": [ "%%time\n", "\n", "points = [(x,y) for x in [1,2,3] for y in [3,4,5] if x != y]\n", "print(points)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[9, 4, 8, 6, 2, 9]" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[y for x in [(9,4),(8,6),(2,9)] for y in x]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "+ #### Using for filtering strings " ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "import string" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~\n", "0123456789\n", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n", "abcdefghijklmnopqrstuvwxyz\n", "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", "0123456789abcdefABCDEF\n" ] } ], "source": [ "print(string.punctuation)\n", "print(string.digits)\n", "print(string.ascii_letters)\n", "print(string.ascii_lowercase)\n", "print(string.ascii_uppercase)\n", "print(string.hexdigits)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that we know the string package, let's use it for cleaning strings with list comprehensions:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "my_string = 'This is a string. It is full of surprises! Would you believe it? I can clean it...'" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['This', 'is', 'a', 'string.', 'It', 'is', 'full', 'of', 'surprises!', 'Would', 'you', 'believe', 'it?', 'I', 'can', 'clean', 'it...']\n" ] } ], "source": [ "tokens = [token for token in my_string.split()]\n", "print(tokens)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['this', 'is', 'a', 'string.', 'it', 'is', 'full', 'of', 'surprises!', 'would', 'you', 'believe', 'it?', 'i', 'can', 'clean', 'it...']\n" ] } ], "source": [ "lowercase_tokens = [token.lower() for token in my_string.split()]\n", "print(lowercase_tokens)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['this', 'is', 'a', 'string', 'it', 'is', 'full', 'of', 'surprises', 'would', 'you', 'believe', 'it', 'i', 'can', 'clean', 'it']\n" ] } ], "source": [ "lower_strip_tokens = [token.strip(string.punctuation).lower() for token in my_string.split()]\n", "print(lower_strip_tokens)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2) Set Comprehensions:\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Set comprehensions returns a set filled with elements derived from a sequence or iterable, being modified or not. The only difference is that the results are a set instead of a list, that is, without repeated elements and not following a specific order \n", "\n", "The patterns are: \n", "\n", " { for in }\n", " { for in if }\n", " { if else for in }\n", " { if else for in if }\n", "\n", "See the examples below: " ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'e', 'o'}\n" ] } ], "source": [ "vowels = {letter for letter in \"python lovers\" if letter in \"aeiou\"}\n", "print(vowels)" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "set" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(vowels)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'s', 'c', 'p', 'r', 'm'}\n" ] } ], "source": [ "consonants = {letter for letter in 'summer camp' if letter not in \"aeiou\" and letter != ' '}\n", "print(consonants)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3) Dict Comprehensions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Dict comprehensions returns a dictionary filled with elements derived from sequences or iterable, being modified or not. The pattern is a varies a bit from list and set comprehensions, because we have keys and values deriving from a sequence.\n", "\n", "See the examples below: " ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'first': 1, 'second': 2}\n", "\n" ] } ], "source": [ "my_dict = {k:v for k,v in [('first',1),('second',2)]}\n", "print(my_dict)\n", "print(type(my_dict))" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{0: 0, 1: 1, 2: 4, 3: 9}\n" ] } ], "source": [ "squares = {x:x**2 for x in range(4)}\n", "print(squares)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "+ #### Using _zip_ to merge two sequences in a list of tuples: " ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{0: 5, 1: 6, 2: 7, 3: 8}" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "{x:y for x,y in zip(range(5), range(5,9))}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "+ #### Three ways to do the same thing" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'one': 1, 'two': 2, 'three': 3}\n", "CPU times: user 247 µs, sys: 64 µs, total: 311 µs\n", "Wall time: 202 µs\n" ] } ], "source": [ "%%time\n", "\n", "new_dict = dict([('one',1),('two',2),('three',3)])\n", "print(new_dict)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'one': 1, 'two': 2, 'three': 3}\n", "CPU times: user 87 µs, sys: 24 µs, total: 111 µs\n", "Wall time: 114 µs\n" ] } ], "source": [ "%%time\n", "\n", "new_dict = {x:y for x,y in [('one',1),('two',2),('three',3)]}\n", "print(new_dict)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'one': 1, 'two': 2, 'three': 3}\n", "CPU times: user 75 µs, sys: 21 µs, total: 96 µs\n", "Wall time: 99.4 µs\n" ] } ], "source": [ "%%time\n", "\n", "new_dict = {x:y for x,y in zip(['one', 'two', 'three'],[1 ,2 ,3])}\n", "print(new_dict)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "+ #### Inverting key and value" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'one': 1, 'two': 2, 'three': 3}" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "new_dict" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{1: 'one', 2: 'two', 3: 'three'}" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dict_new = {value:key for key, value in new_dict.items()}\n", "dict_new" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "+ #### Increasing a value" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'one': 2, 'two': 3, 'three': 4}" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plus_one = {key:value + 1 for key, value in new_dict.items()}\n", "plus_one" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "+ #### Two ways for converting lists of tuples: " ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "list_of_tuples = [(2,3),(4,5),(1,7)]" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 5 µs, sys: 1 µs, total: 6 µs\n", "Wall time: 9.78 µs\n" ] }, { "data": { "text/plain": [ "{2: 3, 4: 5, 1: 7}" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%time\n", "\n", "dict(list_of_tuples)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 4 µs, sys: 1 µs, total: 5 µs\n", "Wall time: 7.87 µs\n" ] }, { "data": { "text/plain": [ "{2: 3, 4: 5, 1: 7}" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%time\n", "\n", "{key:value for key, value in list_of_tuples}" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [], "source": [ "lista = [[x for x in range(12)],[x**2 for x in range(5)]]" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [0, 1, 4, 9, 16]]" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lista" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### [Generator Expressions](https://www.programiz.com/python-programming/generator) \n", "\n", "Generator expressions are similar to generator functions, but they are created like list comprehensions using simple brackets instead of square brackets " ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "generator" ] }, "execution_count": 74, "metadata": {}, "output_type": "execute_result" } ], "source": [ "generator1 = (x**(0.5) for x in range(10) if x%5 == 0 or x%3 == 0)\n", "type(generator1)" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " at 0x7f5eac23ebd0>\n" ] } ], "source": [ "print(generator1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "+ #### One way to materialise the generator is to convert it to a list:" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0.0, 1.7320508075688772, 2.23606797749979, 2.449489742783178, 3.0]" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(generator1)" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(0.0, 1.7320508075688772, 2.23606797749979, 2.449489742783178, 3.0)" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tuple(generator1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "+ #### In order to access each generator element, we can use the command _next_" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [], "source": [ "generator2 = (x**x for x in range(2,99999999999999)) #A really big number. If it was a list, the memory would overflow." ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(generator2)" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "27" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(generator2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "+ #### When a list command materialises the generator, it materializes all its elements and terminates the generator\n", "+ #### If we use _next_ to access it again, it will raise the _StopIteration_ error " ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [], "source": [ "generator3 = (x**2 for x in range(10))" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 80, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(generator3)" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 81, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(generator3)" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[4, 9, 16, 25, 36, 49, 64, 81]" ] }, "execution_count": 82, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(generator3)" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "ename": "StopIteration", "evalue": "", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mStopIteration\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgenerator3\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m#error\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mStopIteration\u001b[0m: " ] } ], "source": [ "next(generator3) #error" ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [], "source": [ "generator4 = (letter for letter in \"abcd\")" ] }, { "cell_type": "code", "execution_count": 85, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'a'" ] }, "execution_count": 85, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(generator4)" ] }, { "cell_type": "code", "execution_count": 86, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'b'" ] }, "execution_count": 86, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(generator4)" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'c'" ] }, "execution_count": 87, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(generator4)" ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'d'" ] }, "execution_count": 88, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(generator4)" ] }, { "cell_type": "code", "execution_count": 89, "metadata": {}, "outputs": [ { "ename": "StopIteration", "evalue": "", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mStopIteration\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgenerator4\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m#error\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mStopIteration\u001b[0m: " ] } ], "source": [ "next(generator4) #error" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [], "source": [ "generator4 = (letter for letter in \"abcd\")" ] }, { "cell_type": "code", "execution_count": 91, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a\n", "b\n", "c\n", "d\n" ] }, { "ename": "StopIteration", "evalue": "", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mStopIteration\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgenerator4\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m#error\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mStopIteration\u001b[0m: " ] } ], "source": [ "while True:\n", " print(next(generator4)) #error" ] }, { "cell_type": "code", "execution_count": 95, "metadata": {}, "outputs": [], "source": [ "generator4 = (letter for letter in \"abcd\")" ] }, { "cell_type": "code", "execution_count": 96, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a\n", "b\n", "c\n", "d\n" ] } ], "source": [ "for element in generator4: # for iterations can handle stop iteration errors\n", " print(element)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "+ #### Each Generators keeps its state, regardless of the iterators calling it:" ] }, { "cell_type": "code", "execution_count": 102, "metadata": {}, "outputs": [], "source": [ "generator4 = (letter for letter in \"abcd\")" ] }, { "cell_type": "code", "execution_count": 104, "metadata": {}, "outputs": [], "source": [ "for ele1 in generator4:\n", " print(\"first for\", ele1)\n", " for ele2 in generator4:\n", " print(\"second for\", ele2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Special generators: _range*_, _zip_, _filter_, _map_ \n", "\n", "Obs:\n", "range is a class of immutable iterable objects. Their iteration behavior can be compared to tuples: you can't call next directly on them; you have to get an iterator by using iter. So no, range is not a proper generator.\n", "+ Ranges are immutable, so they can be used as dictionary keys.\n", "+ Ranges have the start, stop and step attributes (since Python 3.3), count and index methods and they support in, len and __getitem__ operations.\n", "* You can iterate over the same range multiple times.\n" ] }, { "cell_type": "code", "execution_count": 125, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "range" ] }, "execution_count": 125, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r = range(10)\n", "type(r)" ] }, { "cell_type": "code", "execution_count": 126, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['__bool__',\n", " '__class__',\n", " '__contains__',\n", " '__delattr__',\n", " '__dir__',\n", " '__doc__',\n", " '__eq__',\n", " '__format__',\n", " '__ge__',\n", " '__getattribute__',\n", " '__getitem__',\n", " '__gt__',\n", " '__hash__',\n", " '__init__',\n", " '__init_subclass__',\n", " '__iter__',\n", " '__le__',\n", " '__len__',\n", " '__lt__',\n", " '__ne__',\n", " '__new__',\n", " '__reduce__',\n", " '__reduce_ex__',\n", " '__repr__',\n", " '__reversed__',\n", " '__setattr__',\n", " '__sizeof__',\n", " '__str__',\n", " '__subclasshook__',\n", " 'count',\n", " 'index',\n", " 'start',\n", " 'step',\n", " 'stop']" ] }, "execution_count": 126, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dir(r)" ] }, { "cell_type": "code", "execution_count": 124, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "'range' object is not an iterator", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mr\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m#error\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: 'range' object is not an iterator" ] } ], "source": [ "next(r) #error" ] }, { "cell_type": "code", "execution_count": 115, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 115, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r2 = iter(r)" ] }, { "cell_type": "code", "execution_count": 127, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['__class__',\n", " '__delattr__',\n", " '__dir__',\n", " '__doc__',\n", " '__eq__',\n", " '__format__',\n", " '__ge__',\n", " '__getattribute__',\n", " '__gt__',\n", " '__hash__',\n", " '__init__',\n", " '__init_subclass__',\n", " '__iter__',\n", " '__le__',\n", " '__length_hint__',\n", " '__lt__',\n", " '__ne__',\n", " '__new__',\n", " '__next__',\n", " '__reduce__',\n", " '__reduce_ex__',\n", " '__repr__',\n", " '__setattr__',\n", " '__setstate__',\n", " '__sizeof__',\n", " '__str__',\n", " '__subclasshook__']" ] }, "execution_count": 127, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dir(r2)" ] }, { "cell_type": "code", "execution_count": 121, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 121, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(r2)" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "zip" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "z = zip([1,2,3],[4,5,6],[6,7,8])\n", "type(z)" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "filter" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f = filter(str.isupper,['a','A','E','r'])\n", "type(f)" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "map" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "m = map(int,['1', '2', '3'])\n", "type(m)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.5" } }, "nbformat": 4, "nbformat_minor": 4 }