{ "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": [ "Don't do this." ] }, { "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": [ "### Use comprehensions!" ] }, { "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": [ "Don't do it like this." ] }, { "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": [ "### Do it like this!" ] }, { "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": [ "Don't do it like this." ] }, { "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": [ "### Do it like this!" ] }, { "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": [ "Don't do it like this." ] }, { "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": [ "### This is much better!" ] }, { "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": [ "Don't do it like this." ] }, { "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": [ "### Do it like this!" ] }, { "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": [ "Instead of doing this." ] }, { "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": [ "### You can do it like this!" ] }, { "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": [ "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." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "show_person_details('John Doe', True, False, 83)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### This is much better!" ] }, { "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": [ "### Extra: forcing keyword only argument usage with `*`" ] }, { "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": [ "Don't do it like this." ] }, { "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": [ "### Do it like this!" ] }, { "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": [ "Don't do something like this." ] }, { "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": [ "### This is the Pythonic way!" ] }, { "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 }