{
 "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.

file: generators_comprehension_iterators.ipynb


Back to top

COMP9021 15s2 (Principles of Programming) is powered by WebCMS3
CRICOS Provider No. 00098G