607 lines
13 KiB
Plaintext
607 lines
13 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Idiomatic Python - miscellaneous part 1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Comprehensions"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"original_data = (1, 2, 3, 4)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"<font color='red'>Don't do this.</font>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# list\n",
|
|
"square_roots_list = []\n",
|
|
"for val in original_data:\n",
|
|
" square_root = val**(1/2) \n",
|
|
" square_roots_list.append(square_root)\n",
|
|
"print(square_roots_list)\n",
|
|
"\n",
|
|
"# set\n",
|
|
"square_roots_set = set()\n",
|
|
"for val in original_data:\n",
|
|
" square_root = val**(1/2) \n",
|
|
" square_roots_set.add(square_root)\n",
|
|
"print(square_roots_set)\n",
|
|
"\n",
|
|
"# dict\n",
|
|
"square_roots_dict = {}\n",
|
|
"for val in original_data:\n",
|
|
" square_root = val**(1/2) \n",
|
|
" square_roots_dict[val] = square_root\n",
|
|
"print(square_roots_dict) \n",
|
|
"\n",
|
|
"# dict with a condition\n",
|
|
"integer_square_roots_dict = {}\n",
|
|
"for val in original_data:\n",
|
|
" square_root = val**(1/2)\n",
|
|
" if square_root.is_integer():\n",
|
|
" integer_square_roots_dict[val] = square_root\n",
|
|
"print(integer_square_roots_dict) "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### <font color='green'>Use comprehensions!</font>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"square_roots_list = [val**(1/2) for val in original_data]\n",
|
|
"print(square_roots_list)\n",
|
|
"\n",
|
|
"square_roots_set = {val**(1/2) for val in original_data}\n",
|
|
"print(square_roots_set)\n",
|
|
"\n",
|
|
"square_roots_dict = {val: val**(1/2) for val in original_data}\n",
|
|
"print(square_roots_dict)\n",
|
|
"\n",
|
|
"integer_square_roots_dict = {\n",
|
|
" val: val**(1/2)\n",
|
|
" for val in original_data if (val**(1/2)).is_integer()\n",
|
|
"}\n",
|
|
"print(integer_square_roots_dict)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Using `in` for checking presence of an element in a collection"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"name = 'John Doe'"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"<font color='red'>Don't do it like this.</font>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"if name == 'John' or name == 'Doe' or name == 'John Doe':\n",
|
|
" print('This seems to be our guy')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### <font color='green'>Do it like this!</font>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"if name in ('John', 'Doe', 'John Doe'):\n",
|
|
" print('This seems to be our guy')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Chained comparisons"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"a, b, c, d = 1, 2, 3, 4"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"<font color='red'>Don't do it like this.</font>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"if b > a and c > b and d > c:\n",
|
|
" print('from lowest to highest: a, b, c, d')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### <font color='green'>Do it like this!</font>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"if a < b < c < d:\n",
|
|
" print('from lowest to highest: a, b, c, d')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Falsy/truthy values"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# These are falsy\n",
|
|
"my_list = []\n",
|
|
"my_dict = {}\n",
|
|
"my_set = set()\n",
|
|
"my_tuple = tuple()\n",
|
|
"zero = 0\n",
|
|
"false = False\n",
|
|
"none = None\n",
|
|
"my_str = ''\n",
|
|
"\n",
|
|
"# Basically the rest are truthy\n",
|
|
"# for example:\n",
|
|
"my_second_list = ['foo']"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"<font color='red'>Don't do it like this.</font>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"if len(my_list) == 0:\n",
|
|
" print('Empty list is so empty')\n",
|
|
" \n",
|
|
"if not len(my_dict):\n",
|
|
" print('Empty dict is also very empty')\n",
|
|
" \n",
|
|
"if not len(my_set) and not len(my_tuple):\n",
|
|
" print('Same goes for sets and tuples')\n",
|
|
" \n",
|
|
"if not bool(zero) and not bool(false) and not bool(none) and len(my_str) == 0:\n",
|
|
" print('These are also falsy')\n",
|
|
" \n",
|
|
"if len(my_second_list) > 0:\n",
|
|
" print('This should be true')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### <font color='green'>This is much better!</font>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"if not my_list:\n",
|
|
" print('Empty list is so empty')\n",
|
|
" \n",
|
|
"if not my_dict:\n",
|
|
" print('Empty dict is also very empty')\n",
|
|
" \n",
|
|
"if not my_set and not my_tuple:\n",
|
|
" print('Same goes for sets and tuples')\n",
|
|
" \n",
|
|
"if not zero and not false and not none and not my_str:\n",
|
|
" print('These are also falsy')\n",
|
|
" \n",
|
|
"if my_second_list:\n",
|
|
" print('This should be true')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## `any` & `all`"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"example_collection = ['a', True, 'Python is cool', 123, 0]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"<font color='red'>Don't do it like this.</font>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"any_value_truthy = True\n",
|
|
"for val in example_collection:\n",
|
|
" if val:\n",
|
|
" any_value_truthy = True\n",
|
|
" break\n",
|
|
"\n",
|
|
"all_values_truthy = True\n",
|
|
"for val in example_collection:\n",
|
|
" if not val:\n",
|
|
" all_values_truthy = False\n",
|
|
" break\n",
|
|
" \n",
|
|
"print('any truthy: {}, all truthy: {}'.format(any_value_truthy, all_values_truthy))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### <font color='green'>Do it like this!</font>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"any_value_truthy = any(example_collection)\n",
|
|
"all_values_truthy = all(example_collection)\n",
|
|
"print('any truthy: {}, all truthy: {}'.format(any_value_truthy, all_values_truthy))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Pythonic substitute for ternary operator\n",
|
|
"Many other programming languages have a ternary operator: `?`. A common use case for the ternary operator is to assign a certain value to a variable based on some condition. In other words, it could be used like this:\n",
|
|
"```\n",
|
|
"variable = some_condition ? some_value : some_other_value\n",
|
|
"```"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"<font color='red'>Instead of doing this.</font>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"some_condition = True # just a dummy condition\n",
|
|
"\n",
|
|
"if some_condition:\n",
|
|
" variable = 'John'\n",
|
|
"else:\n",
|
|
" variable = 'Doe'\n",
|
|
"print(variable)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### <font color='green'>You can do it like this!</font>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"variable = 'John' if some_condition else 'Doe'\n",
|
|
"print(variable)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Function keywords arguments\n",
|
|
"For better readability and maintainability."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def show_person_details(name, is_gangster, is_hacker, age):\n",
|
|
" print('name: {}, gangster: {}, hacker: {}, age: {}'.format(\n",
|
|
" name, is_gangster, is_hacker, age))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"<font color='red'>This is not good. It's hard to tell what `True`, `False` and `83` refer here if you are not familiar with the signature of the `show_person_details` function.</font>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"show_person_details('John Doe', True, False, 83)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### <font color='green'>This is much better!</font>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"show_person_details('John Doe', is_gangster=True, is_hacker=False, age=83)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### <font color='green'>Extra: forcing keyword only argument usage with `*`</font>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def show_person_details(name, *, is_gangster, is_hacker, age):\n",
|
|
" pass\n",
|
|
"\n",
|
|
"# This won't work anymore because only keyword arguments allowed after *\n",
|
|
"# show_person_details('John Doe', True, False, 83)\n",
|
|
"\n",
|
|
"# This is ok\n",
|
|
"show_person_details('John Doe', is_gangster=True, is_hacker=False, age=83)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Multiple assigment\n",
|
|
"Let's say we want to swap the values of two variables."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"<font color='red'>Don't do it like this.</font>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# original values\n",
|
|
"a = 1\n",
|
|
"b = 2\n",
|
|
"\n",
|
|
"# swap\n",
|
|
"tmp = a\n",
|
|
"a = b\n",
|
|
"b = tmp\n",
|
|
"print(a, b)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### <font color='green'>Do it like this!</font>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# original values\n",
|
|
"a = 1\n",
|
|
"b = 2\n",
|
|
"\n",
|
|
"# swap\n",
|
|
"a, b = b, a\n",
|
|
"print(a, b)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## (Un)packing"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"my_list = [1, 2, 3, 4, 5, 6]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"<font color='red'>Don't do something like this.</font>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"first = my_list[0]\n",
|
|
"last = my_list[-1]\n",
|
|
"middle = my_list[1:-1]\n",
|
|
"print(first, middle, last)\n",
|
|
"\n",
|
|
"packed = [first] + middle + [last]\n",
|
|
"assert packed == my_list"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### <font color='green'>This is the Pythonic way!</font>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# unpacking\n",
|
|
"first, *middle, last = my_list\n",
|
|
"print(first, middle, last)\n",
|
|
"\n",
|
|
"# packing\n",
|
|
"packed = [first, *middle, last]\n",
|
|
"assert packed == my_list"
|
|
]
|
|
}
|
|
],
|
|
"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.5.4"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|