{ "cells": [ { "cell_type": "markdown", "id": "4c858ff7", "metadata": {}, "source": [ "# Unpacking Iterables" ] }, { "cell_type": "markdown", "id": "cc098c5d", "metadata": {}, "source": [ "## A side note about tuples" ] }, { "cell_type": "markdown", "id": "25f62717", "metadata": {}, "source": [ "What defines a tuple in Python, is not **`()`**, but **`,`**" ] }, { "cell_type": "code", "execution_count": 4, "id": "191f1bac", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "<class 'tuple'>\n", "(1, 2, 3)\n" ] } ], "source": [ "x = 1, 2, 3\n", "\n", "print(type(x))\n", "print(x)" ] }, { "cell_type": "markdown", "id": "42ef8f7a", "metadata": {}, "source": [ "The **`()`** are used to make the tuple clearer.\n", "\n", "To create a tuple with a single element:" ] }, { "cell_type": "code", "execution_count": 6, "id": "92da7bcb", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "<class 'int'>\n", "1\n" ] } ], "source": [ "# will not work as intended\n", "x = (1)\n", "\n", "print(type(x))\n", "print(x)" ] }, { "cell_type": "code", "execution_count": 9, "id": "27e466f6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "<class 'tuple'>\n", "(1,)\n" ] } ], "source": [ "x = 1, # or x = (1, ), that is more common\n", "\n", "print(type(x))\n", "print(x)" ] }, { "cell_type": "markdown", "id": "1a2c314d", "metadata": {}, "source": [ "The only exception is when creating an empty tuple:" ] }, { "cell_type": "code", "execution_count": 11, "id": "a38cd058", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "<class 'tuple'>\n", "()\n" ] } ], "source": [ "x = () # or x = tuple()\n", "\n", "print(type(x))\n", "print(x)" ] }, { "cell_type": "markdown", "id": "d349057c", "metadata": {}, "source": [ "## Packed Values" ] }, { "cell_type": "markdown", "id": "e8af6d87", "metadata": {}, "source": [ "Packed values refers to values that are **bundled** together in some way.\n", "\n", "**Tuples** and **Lists** are obvios.\n", "\n", "```python\n", "my_tuple = (1, 2, 3)\n", "my_list = (1, 2, 3)\n", "```\n", "\n", "Even a **string** is considered to be a packed value:\n", "\n", "```python\n", "my_str = \"python\"\n", "```\n", "\n", "**Sets** and **dictionaries** are also packed values:\n", "\n", "```python\n", "my_set = {1, 2, 3}\n", "my_dict = {\"a\": 1, \"b\": 2, \"c\": 3}\n", "```\n", "\n", "In fact, any **iterable** can be considered a packed value." ] }, { "cell_type": "markdown", "id": "9af4130c", "metadata": {}, "source": [ "## Unpacking Packed Values" ] }, { "cell_type": "markdown", "id": "8efd101b", "metadata": {}, "source": [ "Unpacking is tha act of **splitting** packed values into **individual variables** contained in a list or tuple.\n" ] }, { "cell_type": "code", "execution_count": 19, "id": "7c9b2f77", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a=1, b=2, c=3\n" ] } ], "source": [ "# left hand side is a tuple (1, 2, 3)\n", "# right hand side is a list\n", "a, b, c = [1, 2, 3]\n", "\n", "print(f\"{a=}, {b=}, {c=}\")" ] }, { "cell_type": "markdown", "id": "4a0ce8b5", "metadata": {}, "source": [ "The unpacking into individual variables is based on the **position** of each element.\n", "\n", "> Does this remind you of how positional arguments were assigned to parameters in function calls?" ] }, { "cell_type": "markdown", "id": "a4a2d786", "metadata": {}, "source": [ "### Unpacking other Iterables" ] }, { "cell_type": "code", "execution_count": 23, "id": "f6c77b25", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a=10, b=20, c='Hello'\n" ] } ], "source": [ "a, b, c = 10, 20, \"Hello\" # right hand side is a tuple\n", "\n", "print(f\"{a=}, {b=}, {c=}\")" ] }, { "cell_type": "code", "execution_count": 24, "id": "d460b701", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a='X', b='Y', c='Z'\n" ] } ], "source": [ "a, b, c = \"XYZ\" # right hand side is a string\n", "\n", "print(f\"{a=}, {b=}, {c=}\")" ] }, { "cell_type": "markdown", "id": "3135cb40", "metadata": {}, "source": [ "Instead of writing\n", "```python\n", "a = 10\n", "b = 20\n", "```\n", "we can write\n", "```python\n", "a, b = 10, 20\n", "```\n", "\n", "In fact, unpacking works with any **iterable** type." ] }, { "cell_type": "markdown", "id": "3ff7f3b0", "metadata": {}, "source": [ "## Simple Application of Unpacking" ] }, { "cell_type": "markdown", "id": "34f02c27", "metadata": {}, "source": [ "Swapping values of two variables\n", "\n", "```python\n", "a = 10 -> a = 20\n", "b = 20 -> b = 10\n", "```" ] }, { "cell_type": "code", "execution_count": 30, "id": "997ce50f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a=10, b=20\n", "a=20, b=10\n" ] } ], "source": [ "# traditional approach\n", "a = 10\n", "b = 20\n", "print(f\"{a=}, {b=}\")\n", "\n", "tmp = a\n", "a = b\n", "b = tmp\n", "print(f\"{a=}, {b=}\")" ] }, { "cell_type": "code", "execution_count": 31, "id": "ac44f156", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a=10, b=20\n", "a=20, b=10\n" ] } ], "source": [ "# using unpacking \n", "a = 10\n", "b = 20\n", "print(f\"{a=}, {b=}\")\n", "\n", "a, b = b, a\n", "print(f\"{a=}, {b=}\")" ] }, { "cell_type": "markdown", "id": "2e0847c8", "metadata": {}, "source": [ "This works because in Python, the entire RHS is evaluated **first** and **completely**.\n", "\n", "**then** assinments are made to the LHS." ] }, { "cell_type": "markdown", "id": "9ab6f743", "metadata": {}, "source": [ "### Unpacking Sets and Dictionaries" ] }, { "cell_type": "code", "execution_count": 1, "id": "f1ea6324", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "key1\n", "key2\n", "key3\n" ] } ], "source": [ "d = {\n", " \"key1\": 1,\n", " \"key2\": 2,\n", " \"key3\": 3\n", "}\n", "\n", "for e in d: # e iterates through the keys of dictionary\n", " print(e)\n", " \n", " \n", "# for e in d.keys():\n", "# print(e)" ] }, { "cell_type": "code", "execution_count": 4, "id": "ec201282", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n", "3\n" ] } ], "source": [ "for e in d.values(): # e iterates through the values of dictionary\n", " print(e)" ] }, { "cell_type": "code", "execution_count": 6, "id": "00c42b0d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('key1', 1)\n", "('key2', 2)\n", "('key3', 3)\n" ] } ], "source": [ "for e in d.items():\n", " print(e)" ] }, { "cell_type": "markdown", "id": "f7264216", "metadata": {}, "source": [ "So, when unpacking **`d`**, we are actually unpacking the **keys** of **`d`**." ] }, { "cell_type": "code", "execution_count": 6, "id": "c9d39f09", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a='key1', b='key2', c='key3'\n" ] } ], "source": [ "a, b, c = d\n", "\n", "print(f\"{a=}, {b=}, {c=}\")" ] }, { "cell_type": "markdown", "id": "64aca275", "metadata": {}, "source": [ "> Notice\n", "```python\n", "a, b, c = d\n", "```\n", "`a = 'key1'`, `b = 'key2'`, `c = 'key3'` or\n", "\n", "`a = 'key2'`, `b = 'key3'`, `c = 'key1'` or \n", "\n", "`a = 'key1'`, `b = 'key3'`, `c = 'key2'` or\n", "\n", "etc...\n", "\n", "> **Distionaries** and **Sets** are **Unordered** types.\n", ">\n", "> They can be iterated, but there is **no guarantee** the order of the results will match your literal!\n", "\n", "In practice, we rarely unpack sets and dictionaries in precisely this way." ] }, { "cell_type": "markdown", "id": "f0164eb0", "metadata": {}, "source": [ "### Example using Sets" ] }, { "cell_type": "code", "execution_count": 16, "id": "7bd5b062", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "c\n", "e\n", "f\n", "d\n", "b\n", "a\n" ] } ], "source": [ "s = {\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"}\n", "\n", "for e in s: # there is no gaurantee the oerder of the result\n", " print(e)" ] }, { "cell_type": "code", "execution_count": 18, "id": "e5fa44fa", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a='c', b='e', c='f', d='d', e='b', f='a'\n" ] } ], "source": [ "a, b, c, d, e, f = s\n", "\n", "print(f\"{a=}, {b=}, {c=}, {d=}, {e=}, {f=}\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.11.4" } }, "nbformat": 4, "nbformat_minor": 5 }