{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "6b4fce18-128e-441d-9040-7d738b1ac1c8",
   "metadata": {},
   "source": [
    "## PDSP 2025, Lecture 10, 9 September 2025"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc20172e-7d1c-4129-bf82-fbfc290eedfc",
   "metadata": {},
   "source": [
    "### Mutable and immutable values\n",
    "- Lists and dictionaries are mutable\n",
    "- `int`, `float`, `bool`, `str`, tuple are immutable"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9aa55b47-a957-4021-bd14-35b8cfb9e7b4",
   "metadata": {},
   "source": [
    "- For immutable values, assignment copies the value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "436ddc14-9f85-4872-bdbe-57d0681542b6",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 5\n",
    "y = x\n",
    "y = 7  # Does not affect the value of x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "6202f9a6-248e-4700-91e5-a54c8b502763",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(5, 7)"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x,y"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "16bc5e68-c08d-496d-a208-872ddd715e05",
   "metadata": {},
   "source": [
    "- For mutable values, assigment *aliases* the new name to point to the same value as the old name\n",
    "- Updating through either name affects both"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "e8bd506c-466f-45a0-9f0c-04dac409624e",
   "metadata": {},
   "outputs": [],
   "source": [
    "l1 = [1,2,3]\n",
    "l2 = l1\n",
    "l2[0] = 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "24d5f326-5efb-4187-a593-e87fd2f697d5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([4, 2, 3], [4, 2, 3])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l1,l2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "b178d223-0eed-4986-8456-3460ef59ff8c",
   "metadata": {},
   "outputs": [],
   "source": [
    "l1[2] = 6"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "2d1f5e33-937e-40f9-96a5-bbee63d6c961",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([4, 2, 6], [4, 2, 6])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l1,l2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9f4af5c2-89a8-41ad-85c9-2cb228317549",
   "metadata": {},
   "source": [
    "- We can update a mutable value inside a function\n",
    "- However, we should be careful to use updates that do not reassign the name\n",
    "- Use `l.append(v)` vs `l = l + [v]`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "369a28da-b067-4d50-8690-ec4781d2b7b8",
   "metadata": {},
   "outputs": [],
   "source": [
    "def bad(l,v):\n",
    "    l = l + [v]\n",
    "    print(l)\n",
    "    return"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "2c8e8786-2a98-4911-aec1-4d0498d6ae17",
   "metadata": {},
   "outputs": [],
   "source": [
    "def good(l,v):\n",
    "    l.append(v)\n",
    "    print(l)\n",
    "    return"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7fb9addd-ff2c-4675-b070-bfe6653c8110",
   "metadata": {},
   "source": [
    "- `bad(l,v)` appends `v` within the function, but creates a new copy of `l` in the process, that is different from the `l` passed as an argument"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "5f61b906-9c44-4d93-9403-b2c6a30b9718",
   "metadata": {},
   "outputs": [],
   "source": [
    "l = [1,2,3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "f6453516-7653-42bc-a02b-230020db6353",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4]\n"
     ]
    }
   ],
   "source": [
    "bad(l,4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "ab2c54e8-d86d-4770-a46c-021c780784ba",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3]"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f1cee5f9-fb8f-4242-87a9-cadf193a29ac",
   "metadata": {},
   "source": [
    "`good(l,v)` on the other hand updates `l` in place, so the effect is visible outside"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "7f764877-ea20-4709-98d3-143472569603",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3]"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "9965ff38-84eb-49eb-9623-5a29366e8683",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4]\n"
     ]
    }
   ],
   "source": [
    "good(l,4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "8aec380e-ef08-4468-9b70-946a9d6c4c49",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4]"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ea751459-36b4-4675-b718-5a37ee60eef9",
   "metadata": {},
   "source": [
    "- We can update `bad(l,v)` to return the modified list, but then we have to reassign `l` to the returned value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "f3dae929-af8a-47e3-b776-724af97cf1d9",
   "metadata": {},
   "outputs": [],
   "source": [
    "def bad2(l,v):\n",
    "    l = l + [v]\n",
    "    print(l)\n",
    "    return(l)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "c8725ae7-4646-4e77-8a60-9c62b064d4f7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4]\n"
     ]
    }
   ],
   "source": [
    "l = [1,2,3]\n",
    "returnlist = bad2(l,4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "8586a33d-42ed-4838-8b4b-4f051f4255ff",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 3], [1, 2, 3, 4])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l,returnlist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "0b0c7960-d90b-4234-9eb7-e1546695f3ef",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4]\n"
     ]
    }
   ],
   "source": [
    "l = [1,2,3]\n",
    "l = bad2(l,4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "9ed13a7c-698f-4da9-ae4d-3c8f44c1d481",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4]"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe986201-b1e1-4ecc-ac72-86413cf37d76",
   "metadata": {},
   "source": [
    "### Slices and copying lists\n",
    "- A slice creates a new list\n",
    "- Full slice `l[:]` is a faithful copy of `l`\n",
    "    - Abbreviation for `l[0:len(l)]`\n",
    "- Assigning a full slice makes a disjoint copy of a list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "a8cf63bb-6232-46e7-b43f-23b206a29047",
   "metadata": {},
   "outputs": [],
   "source": [
    "l1 = [1,2,3]\n",
    "l2 = l1[:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "24d776a8-9c5c-481a-b227-96dee10df3af",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 3], [1, 2, 3])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l1,l2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "5f68ceac-dd43-4a80-9166-41101f1cdc3d",
   "metadata": {},
   "outputs": [],
   "source": [
    "l1[2] = 6\n",
    "l2[0] = 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "9fce6893-abc2-4ba1-bfba-1f9253796e2f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 6], [4, 2, 3])"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l1, l2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f7cbf47e-2d74-4870-bb58-e58f1ca9d9a2",
   "metadata": {},
   "source": [
    "### Pitfalls of mutability"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "1989a16d-aaf8-4dba-a4fb-e525a737132b",
   "metadata": {},
   "outputs": [],
   "source": [
    "zerorow = [0,0,0]\n",
    "zeromat = [zerorow, zerorow, zerorow]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "9c59d8ba-47ad-4c3b-8418-9cb835ce1094",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[0, 0, 0], [0, 0, 0], [0, 0, 0]]"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "zeromat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "b4dcf542-8439-4af2-872f-2f98db0c0447",
   "metadata": {},
   "outputs": [],
   "source": [
    "zeromat[2][2] = 33"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "0baad6b3-21e8-4111-997d-cdc1d0ed7e07",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[0, 0, 33], [0, 0, 33], [0, 0, 33]]"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "zeromat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "cdb4ec88-c27f-43b8-8cc1-f860547d1300",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 0, 33]"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "zerorow"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "26b3a832-4ff5-42fa-9d00-df12472c4db7",
   "metadata": {},
   "source": [
    "- This happens because updating any row in `zeromat` impliciltly updates `zerolist`\n",
    "- And vice versa"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "a1f9a93d-81f3-4f4b-9ef1-4b2dc6481ddb",
   "metadata": {},
   "outputs": [],
   "source": [
    "zerorow[0] = 11"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "dc07d4e3-4437-4c17-b93a-8316b1e4a4d6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[11, 0, 33], [11, 0, 33], [11, 0, 33]]"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "zeromat"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ab05bc2e-05a2-45bd-9dfc-67bdb6ec5d0e",
   "metadata": {},
   "source": [
    "### An aside\n",
    "- Multiplication is repeated addtion: $n \\times m = \\underbrace{n+n+\\cdots+n}_{\\text{m~times}}$\n",
    "- For lists, `+` denotes concatenation\n",
    "- `l+l+l+l` can be written as `l*4`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "2d6a018b-89eb-4b22-b0bb-c69f20fc1906",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "12"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "4 + 4 + 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "ff3ceb59-a823-4ac7-a954-1262c7bfabeb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "12"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "4*3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "58c7eec7-b44f-4bb5-96b3-61a813f5aba0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 0, 0, 0, 0, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[0,0,0] + [0,0,0] + [0,0,0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "f005e45a-51ef-411e-aa36-0cb2031501da",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 0, 0, 0, 0, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[0,0,0]*3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "92b7d745-f17d-4753-bfde-8fdc5c2666e6",
   "metadata": {},
   "source": [
    "- This does not avoid list aliasing issues"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "9d58343a-c3d6-4aa0-93ad-e09acc1299f4",
   "metadata": {},
   "outputs": [],
   "source": [
    "zerorow = [0,0,0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "7f9949fa-3db7-4eb4-afc6-51893ee20d2a",
   "metadata": {},
   "outputs": [],
   "source": [
    "zerolist = [zerorow]*3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "4f519a24-5524-4c95-84f8-83716fe51057",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[0, 0, 0], [0, 0, 0], [0, 0, 0]]"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "zerolist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "f794a266-e2a6-4aa3-8bbd-409fdf90fc0f",
   "metadata": {},
   "outputs": [],
   "source": [
    "zerolist[1][1] = 44"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "02632bda-2eee-48bb-9153-ae62fd592404",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[0, 44, 0], [0, 44, 0], [0, 44, 0]]"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "zerolist"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "621ada1e-a39c-4e59-9579-73c3dd55103b",
   "metadata": {},
   "source": [
    "- Use list comprehension instead\n",
    "- Each list comprehension creates a new list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "bf264fc7-9e9f-4dcf-80c3-74a7d4911594",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 0, 0]"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[ 0 for i in range(3) ]  # A list of 3 zeros"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "b78463cd-c537-4bd1-9320-3cda061f40dd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[0, 0, 0], [0, 0, 0], [0, 0, 0]]"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[ [ 0 for i in range(3) ] for j in range (3) ] # 3 disjoint lists of 3 zeros"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "02d313ea-5fd4-4647-8c13-449c2e682120",
   "metadata": {},
   "outputs": [],
   "source": [
    "zmat = [ [ 0 for i in range(3) ] for j in range (3) ] "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "6ecaed32-70ba-4e3c-9a3a-ffd354b89ad0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[0, 0, 0], [0, 0, 0], [0, 0, 0]]"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "zmat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "0f5da8b5-390e-461f-a6e4-f3c8536d807a",
   "metadata": {},
   "outputs": [],
   "source": [
    "zmat[1][1] = 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "67385435-9204-47ee-b2a7-1e36efa77e5e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[0, 0, 0], [0, 1, 0], [0, 0, 0]]"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "zmat"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f25b5466-485e-4c8b-88f1-5b54bbcf8c47",
   "metadata": {},
   "source": [
    "### Calling functions\n",
    "- Suppose we have a function definition `def f(a,b):` and a function call `f(x,y)`\n",
    "- When `f(x,y)` is executed, it is as though we start `f` with the assignments\n",
    "```\n",
    "    a = x\n",
    "    b = y\n",
    "```\n",
    "- This explains how/when values can be updated within a function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "015b86a8-0fae-4296-a40d-467f27e12222",
   "metadata": {},
   "outputs": [],
   "source": [
    "def factorial(n):\n",
    "    ans = 1\n",
    "    while n >= 1:\n",
    "        ans = ans * n\n",
    "        n = n-1\n",
    "    return(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "52622e0c-9c7f-4cf7-bbe5-df5c324de19c",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 6\n",
    "y = factorial(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "dde6d0d4-76d5-4b02-a7af-40a4b01592ec",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(6, 720)"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x,y"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "49ebd9c5-0854-4229-a0a9-166bd49ba8cb",
   "metadata": {},
   "source": [
    "- Inside the function, the parameter `n` is decremented to `0`\n",
    "- `n` is derived from the variable `x` passed when the function is called\n",
    "- Since `x` is immutable, the implicit assignment `n = x` *copies* the value of `x` into `n`\n",
    "- Updating `n` has no effect on `x`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "52acb8b0-9dbb-4bba-a5c9-dfe17a03f3a1",
   "metadata": {},
   "source": [
    "- This also means we cannot write a function `swap` along the following lines"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "f74e379f-2a13-4c06-af40-a52efccd5965",
   "metadata": {},
   "outputs": [],
   "source": [
    "def swap(x,y):\n",
    "    (x,y) = (y,x)\n",
    "    return"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "3402481f-e7aa-4714-8e98-73129987de99",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = 5\n",
    "n = 7\n",
    "swap(m,n)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "72f85b60-5532-4f24-a56a-73ffc8ce4bad",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(5, 7)"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m,n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f8123fa8-907e-41e5-81f8-754f34cdd771",
   "metadata": {},
   "source": [
    "- This will not work with mutable values either\n",
    "- The problem is the reassignment inside the function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "7d37d9a0-223e-4b1f-b00e-9491b2d9cb75",
   "metadata": {},
   "outputs": [],
   "source": [
    "list1 = [1,2,3]\n",
    "list2 = [4,5,6]\n",
    "swap(list1,list2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "dfa40284-283c-44cb-9ca1-b0d8fe183c00",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 3], [4, 5, 6])"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list1, list2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "41a06c77-3b16-4394-883f-4725d59cfb64",
   "metadata": {},
   "source": [
    "### Passing mutable values to a function\n",
    "- Passing an argument is like executing an assignment statement before starting the function\n",
    "- For mutable values, this aliases the function parameter to the called value\n",
    "- In place changes in the function affect the value outside the function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "d7ad990e-84b4-4aee-8933-85945f4b377c",
   "metadata": {},
   "outputs": [],
   "source": [
    "def concat(l1,l2):\n",
    "    l1.extend(l2)\n",
    "    return"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "f60acfaf-e519-4591-8df9-ba1104f108df",
   "metadata": {},
   "outputs": [],
   "source": [
    "l3 = [1,2,3]\n",
    "l4 = [4,5,6]\n",
    "concat(l3,l4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "1c88145f-8e48-4835-b301-8bfabdf8a972",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 3, 4, 5, 6], [4, 5, 6])"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l3,l4"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bcea13c6-673b-4df9-b9e5-004678c5f2f3",
   "metadata": {},
   "source": [
    "- If we pass a slice, the value in the function is a disjoint copy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "279ef5a3-2264-4883-b25c-9164e98c1e53",
   "metadata": {},
   "outputs": [],
   "source": [
    "l3 = [1,2,3]\n",
    "l4 = [4,5,6]\n",
    "concat(l3[:],l4[:])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "4405d018-3f96-4ade-9680-560c14cd9e60",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 3], [4, 5, 6])"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l3,l4"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6da228e5-f7d3-4e48-a661-06f8570af45a",
   "metadata": {},
   "source": [
    "- However, reassigning the variable inside the function creates a new value not connected to the outer value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "id": "40e4be65-f6ed-427f-8999-abcc98239f08",
   "metadata": {},
   "outputs": [],
   "source": [
    "def concat2(l1,l2):\n",
    "    l1 = l1 + l2\n",
    "    return"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "df61282e-b6e7-4f17-89b9-e4f948c1f742",
   "metadata": {},
   "outputs": [],
   "source": [
    "l3 = [1,2,3]\n",
    "l4 = [4,5,6]\n",
    "concat2(l3,l4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "id": "6730426d-4d9c-43f1-b3f7-6bc773197b34",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 3], [4, 5, 6])"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l3,l4  # No effect - reassignment in function creates a local copy"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e553ebd8-fecd-4146-8137-a3612999229a",
   "metadata": {},
   "source": [
    "- In fact, our problem with `swap()` applies to mutable values as well\n",
    "- The statement `(m,n) = (n,m)` is a reassignment and creates new values inside the function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "id": "a96d6988-b967-4ed3-82a2-86897a02591a",
   "metadata": {},
   "outputs": [],
   "source": [
    "swap(l3,l4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "id": "7dae841d-45cb-4009-b0b8-8e3a8b23b879",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 3], [4, 5, 6])"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l3,l4"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4275450f-89d1-4bd5-a0ad-be6e5b9e37a0",
   "metadata": {},
   "source": [
    "- Be careful not to mix reassignment with in-place modification\n",
    "- What is the outcome of the following?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "id": "c3939588-8afa-4c93-859d-6a64f8f076ca",
   "metadata": {},
   "outputs": [],
   "source": [
    "def myappend(l,x):\n",
    "    l = l.append(x)\n",
    "    return(l)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "id": "b4028812-d705-4139-961a-295236fe6f7a",
   "metadata": {},
   "outputs": [],
   "source": [
    "l1 = [1,2]\n",
    "l1 = myappend(l1,3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "id": "ddc81865-8cde-4ea3-a4b7-90814c3bd0d2",
   "metadata": {},
   "outputs": [],
   "source": [
    "l1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "1e020be6-e3bb-40f1-b4c4-ac4c4f47defc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n"
     ]
    }
   ],
   "source": [
    "print(l1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe3caab7-9b51-4c70-87d7-95cc1c3be3cd",
   "metadata": {},
   "source": [
    "- `None` is a special value in Python that explicitly represents that no value is assigned\n",
    "- A function that does not return a value returns `None`\n",
    "- In the notebook, the value is \"empty\", but `print()` displays it as `None`\n",
    "    - In other words, `str(None)` converts the value `None` to the string `\"None\"`\n",
    "- `None` has its own type which is not compatible with any other type, so no operations are legal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "id": "a16285fc-fd6b-4a64-9616-594deff8bf87",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'None'"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "str(None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "id": "7803b20a-1153-4d43-8fab-f60ea141b3c0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n"
     ]
    }
   ],
   "source": [
    "print(None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "id": "b18e0629-d3ca-4d72-b571-9d9db075ba7e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "NoneType"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(None)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5049e36d-c33e-43e1-8d79-4eb4d90101e7",
   "metadata": {},
   "source": [
    "- Setting a variable to `None` is different from leaving it undefined"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "id": "ca5b3a9c-57fc-4edf-9eb3-65803ba452fc",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 7"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "id": "2e57380f-26d3-497d-b9b7-46f12cd20313",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "int"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "id": "32ea46c7-b466-498a-8a45-1a95e74e88d0",
   "metadata": {},
   "outputs": [],
   "source": [
    "del(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "id": "c2c9a7d8-cf18-4154-bf48-c972a2221cb4",
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'x' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mNameError\u001b[39m                                 Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[74]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[43mx\u001b[49m\n",
      "\u001b[31mNameError\u001b[39m: name 'x' is not defined"
     ]
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "id": "357e46d6-f797-435a-a669-8f40a5e11ba8",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "id": "c43e9e8d-ba29-4c2e-a127-cfee03f5453a",
   "metadata": {},
   "outputs": [],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dbe47d9c-8b7a-4d12-94c0-76c914910999",
   "metadata": {},
   "source": [
    "- We can test if a variable is set to `None`\n",
    "- We will use this later"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "id": "393c90d1-47c6-4928-b63e-702048ece34a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 77,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x == None"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "82ec78d5-e501-43e4-8a3c-e25c20242910",
   "metadata": {},
   "source": [
    "### More on equality\n",
    "- `x == y` checks that `x` and `y` contain the same value\n",
    "- An assignment `l2 = l1` aliases `l2` to point to the same list as `l1`\n",
    "    - Naturally, we expect `l2 == l1` to be `True`\n",
    "    - But there is a stronger relationship, because `l1` and `l2` are the *same* value\n",
    "- `x is y` checks if `x` and `y` refer to the same value\n",
    "    - If `x is y` holds, it must be that `x == y`\n",
    "    - Converse is not true"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "id": "41a42332-af00-4a45-ada4-74eb3ee7e0aa",
   "metadata": {},
   "outputs": [],
   "source": [
    "l1 = [1,2,3]\n",
    "l2 = l1\n",
    "l3 = l1[:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "id": "c3ca7e16-21d9-4376-87f7-b70e2c232c78",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(True, True)"
      ]
     },
     "execution_count": 79,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l1 == l2, l1 == l3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "id": "848f7f1d-0b2e-46b7-bee8-824a8407ab40",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(True, False)"
      ]
     },
     "execution_count": 80,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l1 is l2, l1 is l3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1ccb5e8f-9c13-472b-bc1a-283460002d89",
   "metadata": {},
   "source": [
    "- `x is y` can also be tested for immutable values, but the outcome is not useful or reliable"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "id": "44262d53-f13b-40d4-886c-9e8f1a40a8a1",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 5\n",
    "y = x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "id": "e21a4ea4-fed4-41da-be97-ca68259bdc1d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 82,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x is y # Not useful for immutable values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "id": "7d04ac95-e34b-457c-b9b8-a970fa9b968a",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 5\n",
    "y = 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "id": "355d5509-bdc4-4196-b578-79883fa62cbc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x is y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "id": "760ea61a-9673-4791-9475-ed53c7902962",
   "metadata": {},
   "outputs": [],
   "source": [
    "s = \"hello\"\n",
    "t = s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "id": "27d94ab2-d5fb-43a1-9529-ae454cf65358",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s is t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "id": "c457a48d-e06d-467f-86cf-320219ad0e35",
   "metadata": {},
   "outputs": [],
   "source": [
    "s = \"hello\"\n",
    "t = \"hello\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "id": "0d6314cf-56e8-424e-9d51-48b98b12aa0a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 88,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s is t"
   ]
  }
 ],
 "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.13.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
