{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h1 align=\"center\">Generators Comprehension Iterators</h1>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Generators"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from random import randrange\n",
"\n",
"def randomly_generate_random_nonmultiples_of_ten_between_0_and_99():\n",
" while True:\n",
" digit = randrange(0, 100)\n",
" if digit % 10:\n",
" yield digit\n",
" else:\n",
" return\n",
"\n",
"generator = randomly_generate_random_nonmultiples_of_ten_between_0_and_99()\n",
"while True:\n",
" try:\n",
" # Alternative: print(generator.__next__())\n",
" print(next(generator))\n",
" except StopIteration:\n",
" print('A multiple of 10 was generated, which ended the process')\n",
" break"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def generate_multiples_of(n):\n",
" for i in range(1, 10):\n",
" yield n * i\n",
" \n",
"def generate_multiples():\n",
" for n in range(1, 10):\n",
" yield from generate_multiples_of(n)\n",
"\n",
"count = 0\n",
"generator = generate_multiples()\n",
"for e in generator:\n",
" print('{:3d}'.format(e), end = '')\n",
" count += 1\n",
" if count % 9 == 0:\n",
" print()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from random import randint\n",
"\n",
"def randomly_announce_even_or_odd():\n",
" while True:\n",
" if randint(0, 1):\n",
" print('It is odd.')\n",
" else:\n",
" print('It is even.')\n",
" yield\n",
"\n",
"generator = randomly_announce_even_or_odd()\n",
"for i in range(10):\n",
" next(generator)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def yield_and_send():\n",
" sent = None\n",
" i = 0\n",
" while True:\n",
" if sent == None:\n",
" # \"i\" is generated.\n",
" # - If that follows a call to \"__next__()\",\n",
" # \"sent\" then receives the value None.\n",
" # - If that follows a call to \"send()\",\n",
" # \"sent\" then receives the value passed as an argument to \"send()\".\n",
" sent = yield i\n",
" elif sent == 'stop':\n",
" return\n",
" else:\n",
" # Same as above, except that it is \"sent + i\" that is generated.\n",
" sent = yield sent + i\n",
" i += 1\n",
"\n",
"generator = yield_and_send()\n",
"# First \"next()\" has to be issued, \"send()\" cannot be issued.\n",
"print(next(generator))\n",
"# Now either \"next()\" or \"send()\" can be issued:\n",
"# \"yield i\" has last been executed; \n",
"# which of \"__next__()\" or \"send()\" will be called\n",
"# will determine the value that \"sent\" will receive.\n",
"print(next(generator))\n",
"print(next(generator))\n",
"print(generator.send(10))\n",
"print(generator.send(20))\n",
"print(next(generator))\n",
"print(generator.send(30))\n",
"print(next(generator))\n",
"print(next(generator))\n",
"try:\n",
" print(generator.send('stop'))\n",
"except StopIteration:\n",
" print('Generation has been stopped')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Comprehension and generator expressions"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# More generally, any iterable.\n",
"L = [0, 3, 2, 5, 1]\n",
"\n",
"# List comprehension\n",
"print([i * i for i in L])\n",
"print([i * i for i in L if i % 2])\n",
"print()\n",
"# Set comprehension\n",
"print({i * i for i in L})\n",
"print({i * i for i in L if i % 2})\n",
"print()\n",
"# Dictionnary comprehension\n",
"print({i: i * i for i in L})\n",
"print({i: i * i for i in L if i % 2})\n",
"print()\n",
"\n",
"# \"print((i: i * i for i in L))\" and \"print((i: i * i for i in L if i % 2)\" are invalid:\n",
"# there is no tuple comprehension.\n",
"# \"(i: i * i for i in L)\" and \"(i: i * i for i in L if i % 2)\" are generator expressions:\n",
"# the call to \"tuple()\" in \"tuple((i: i * i for i in L))\",\n",
"# the call to \"tuple()\" in \"tuple((i: i * i for i in L if i % 2))\"\n",
"# force the generator to produce all values;\n",
"# the inner parentheses (for \"generator expression\") can be omitted.\n",
"print(tuple(i * i for i in L))\n",
"print(tuple(i * i for i in L if i % 2))\n",
"print()\n",
"for e in (i * i for i in L):\n",
" print(e, end = ' ')\n",
"print()\n",
"for e in (i * i for i in L if i % 2):\n",
" print(e, end = ' ')\n",
"print('\\n')\n",
"\n",
"# List, set and dictionnary comprehension can be achieved with a similar technique:\n",
"print(list(i * i for i in L))\n",
"print(list(i * i for i in L if i % 2))\n",
"print(set(i * i for i in L))\n",
"print(set(i * i for i in L if i % 2))\n",
"print(dict((i, i * i) for i in L))\n",
"print(dict((i, i * i) for i in L if i % 2))\n",
"print()\n",
"# The parentheses for \"generator expression\" can be ommitted here too:\n",
"print(sorted(i * i for i in L))\n",
"# But they cannot be ommitted here:\n",
"print(sorted((i * i for i in L), reverse = True))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"M = [[[111, 112, 113],\n",
" [121, 122, 123],\n",
" [131, 132, 133]],\n",
" [[211, 212, 213],\n",
" [221, 222, 223],\n",
" [231, 232, 233]]]\n",
"\n",
"print([ 2 * element\n",
" for three_rows in M\n",
" for row in three_rows\n",
" for element in row])\n",
"print([ [ [ 2 * element\n",
" for element in row]\n",
" for row in three_rows]\n",
" for three_rows in M])\n",
"print()\n",
"print([ 2 * element\n",
" for three_rows in M\n",
" if three_rows[0][0] // 100 % 2\n",
" for row in three_rows\n",
" if row[0] // 10 % 2\n",
" for element in row\n",
" if element % 2])\n",
"print([ [ [ 2 * element\n",
" for element in row \n",
" if element % 2]\n",
" for row in three_rows \n",
" if row[0] // 10 % 2]\n",
" for three_rows in M \n",
" if three_rows[0][0] // 100 % 2])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Iterators"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# More generally, any iterable.\n",
"R = range(5)\n",
"\n",
"iterator_1 = iter(R)\n",
"print(iterator_1 is R)\n",
"print(next(iterator_1))\n",
"print(next(iterator_1))\n",
"iterator_2 = iter(R)\n",
"print(iterator_2 is iterator_1)\n",
"print(next(iterator_2))\n",
"print(next(iterator_1))\n",
"print(next(iterator_2))\n",
"print()\n",
"\n",
"generator_expression = (e for e in R)\n",
"\n",
"iterator_1 = iter(generator_expression)\n",
"print(iterator_1 is generator_expression)\n",
"print(next(iterator_1))\n",
"print(next(iterator_1))\n",
"iterator_2 = iter(generator_expression)\n",
"print(iterator_2 is iterator_1)\n",
"print(next(iterator_2))\n",
"print(next(iterator_1))\n",
"print(next(iterator_2))\n",
"print()\n",
"\n",
"def generate_R_members():\n",
" for e in R:\n",
" yield e\n",
"\n",
"generator = generate_R_members()\n",
"iterator_1 = iter(generator)\n",
"print(iterator_1 is generator)\n",
"print(next(iterator_1))\n",
"print(next(iterator_1))\n",
"iterator_2 = iter(generator)\n",
"print(iterator_2 is iterator_1)\n",
"print(next(iterator_2))\n",
"print(next(iterator_1))\n",
"print(next(iterator_2))"
]
}
],
"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.4.3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Resource created Wednesday 16 September 2015, 11:44:10 AM.