Skip to content

Instantly share code, notes, and snippets.

@j9ac9k
Created August 22, 2018 01:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save j9ac9k/db24ad5325ba3aa9098c63c347d376e4 to your computer and use it in GitHub Desktop.
Save j9ac9k/db24ad5325ba3aa9098c63c347d376e4 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Iterators"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Sources:\n",
"\n",
"https://nvie.com/posts/iterators-vs-generators/"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![image.png](https://nvie.com/img/relationships.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Generator Function"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"def fib():\n",
" prev, curr = 0, 1\n",
" while True:\n",
" yield curr\n",
" prev, curr = curr, prev + curr\n",
"\n",
"f = fib()"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Called next(f) yields: 1\n",
"Called next(f) yields: 2\n",
"Called next(f) yields: 3\n",
"Called next(f) yields: 5\n",
"Called next(f) yields: 8\n"
]
}
],
"source": [
"for _ in range(5):\n",
" print(f\"Called next(f) yields: {next(f)}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Generator Expressions"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"gen_exp = (x ** 2 for x in range(10) if x % 2 == 0) "
]
},
{
"cell_type": "code",
"execution_count": 10,
"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<ipython-input-10-d097888c6d32>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgen_exp\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mStopIteration\u001b[0m: "
]
}
],
"source": [
"print(next(gen_exp))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Creating Iterables"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import string\n",
"alphabet_iterable = iter(string.ascii_lowercase)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"next(alphabet_iterable)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Itertools\n",
"\n",
"https://docs.python.org/3/library/itertools.html\n",
"\n",
"\n",
"### Infinite Iterators\n",
"* cycle\n",
"* count\n",
"* repeat\n",
"\n",
"### Terminating Iterators\n",
"\n",
"* accumulate\n",
"* chain\n",
"* compress\n",
"* zip_longest\n",
"* ... and more\n",
"\n",
"### Combinations\n",
"\n",
"* permutations\n",
"* combinations\n",
"* combinations_with_replacement"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Functools\n",
"\n",
"https://docs.python.org/3/library/functools.html\n",
"\n",
"* functools.reduce\n",
"* functools.partial"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## More\n",
"\n",
"Itertools and Functools to recreate k-means\n",
"\n",
"https://www.youtube.com/watch?v=ThS4juptJjQ"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Where Does Range Fit In?\n",
"\n",
"Source:\n",
"\n",
"http://treyhunner.com/2018/02/python-range-is-not-an-iterator/"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"test_range = range(10)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"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<ipython-input-13-3e09a998729c>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtest_range\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(test_range)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"5"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"test_range[5]"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"10"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(test_range)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hasattr(test_range, '__iter__')"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"range_iterator"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"type(test_range.__iter__())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Typing Module"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [],
"source": [
"# typing module syntax (new)\n",
"from typing import NamedTuple\n",
"\n",
"class Employee(NamedTuple):\n",
" name: str\n",
" id: int\n",
" \n",
"ogi = Employee(name=\"Ogi\", id=0)"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Ogi'"
]
},
"execution_count": 50,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ogi.name"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0"
]
},
"execution_count": 51,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ogi.id"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Ogi'"
]
},
"execution_count": 52,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ogi[0]"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [
{
"ename": "TypeError",
"evalue": "'Employee' object does not support item assignment",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-53-99142f099809>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mogi\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"Ogy\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m: 'Employee' object does not support item assignment"
]
}
],
"source": [
"ogi[0] = \"Ogy\""
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Ogy'"
]
},
"execution_count": 55,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ogi = ogi._replace(name=\"Ogy\")\n",
"ogi.name"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [],
"source": [
"# old style syntax\n",
"from collections import namedtuple \n",
"\n",
"Employee = namedtuple('Employee', ['name', 'id'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Collections"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Deque"
]
},
{
"cell_type": "code",
"execution_count": 83,
"metadata": {},
"outputs": [],
"source": [
"from collections import deque\n",
"import random\n",
"\n",
"queue = deque()\n",
"queue_list = list()\n",
"\n",
"numbers = list(range(100_000))\n",
"random.shuffle(numbers)\n",
"\n",
"def reset_objects(queue, queue_list):\n",
" queue.clear()\n",
" queue_list.clear()"
]
},
{
"cell_type": "code",
"execution_count": 84,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"29.5 ms ± 3.18 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
]
}
],
"source": [
"%%timeit\n",
"reset_objects(queue, queue_list)\n",
"for number in numbers:\n",
" queue.append(number)\n",
"# queue.appendleft(number)\n",
"\n",
"while queue:\n",
" queue.pop()\n",
"# queue.popleft()"
]
},
{
"cell_type": "code",
"execution_count": 85,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"30.7 ms ± 3.66 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
]
}
],
"source": [
"%%timeit\n",
"reset_objects(queue, queue_list)\n",
"for number in numbers:\n",
" queue_list.append(number)\n",
"# queue_list.insert(0, number)\n",
" \n",
"while queue_list:\n",
" queue_list.pop()\n",
"# queue_list.pop(0)"
]
},
{
"cell_type": "code",
"execution_count": 86,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3.13 s ± 26 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
]
}
],
"source": [
"%%timeit\n",
"reset_objects(queue, queue_list)\n",
"for number in numbers:\n",
"# queue_list.append(number)\n",
" queue_list.insert(0, number)\n",
" \n",
"while queue_list:\n",
"# queue_list.pop()\n",
" queue_list.pop(0)"
]
},
{
"cell_type": "code",
"execution_count": 87,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"26.2 ms ± 2.84 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
]
}
],
"source": [
"%%timeit\n",
"reset_objects(queue, queue_list)\n",
"for number in numbers:\n",
"# queue.append(number)\n",
" queue.appendleft(number)\n",
"\n",
"while queue:\n",
"# queue.pop()\n",
" queue.popleft()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Various Dictionaries"
]
},
{
"cell_type": "code",
"execution_count": 89,
"metadata": {},
"outputs": [],
"source": [
"# lowercase objects have a c-implementation under the hood\n",
"from collections import defaultdict, OrderedDict\n",
"\n",
"\n",
"test_defaultdict = defaultdict(int)\n",
"test_ordereddict = OrderedDict()"
]
},
{
"cell_type": "code",
"execution_count": 90,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0"
]
},
"execution_count": 90,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"test_defaultdict['abc']"
]
},
{
"cell_type": "code",
"execution_count": 91,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"key: first \t value: 1\n",
"key: second \t value: 2\n",
"key: third \t value: 3\n"
]
}
],
"source": [
"test_ordereddict['first'] = 1\n",
"test_ordereddict['second'] = 2\n",
"test_ordereddict['third'] = 3\n",
"\n",
"for key, value in test_ordereddict.items():\n",
" print(f\"key: {key} \\t value: {value}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"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.7.0"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment