{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "6b4fce18-128e-441d-9040-7d738b1ac1c8",
   "metadata": {},
   "source": [
    "## PDSP 2026, Lecture 05, 25 August 2026"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4aa3ced2-2f5e-4435-b9fb-5ecc8e80ace6",
   "metadata": {},
   "source": [
    "### Lists\n",
    "- Sequences of values, indexed by position\n",
    "- For a list with `n` values, valid positions are `0` to `n-1`\n",
    "    - `len(l)` gives the length of a list\n",
    "    - Accessing a position beyond `len(l)-1` results in `IndexError`\n",
    "- Index `-j` is interpreted as `len(l)-j`\n",
    "    - Useful for accessing values from the end of the list\n",
    "    - Valid indices in reverse are `-1`, `-2`, ..., `-len(l)`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8dbe1201-3d56-4abf-889d-319c5ffed710",
   "metadata": {},
   "source": [
    "### Slices\n",
    "- `l[i:j]` returns the list `[l[i], l[i+1], ..., l[j-1]]`\n",
    "- `l[i:]` -- missing upper bound defaults to `len(l)`\n",
    "- `l[:i]` -- missing lower bound defaults to `0`\n",
    "- `l[:]` -- *full* slice, returns a copy of the entire list"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0aa73a52-4791-4782-9208-77cd277207d9",
   "metadata": {},
   "source": [
    "### More about `range()`\n",
    "- Optional third argument is the step size\n",
    "    - `range(i,j,k)` is `i,i+k,...,i+mk` for the largest `m` such that `i+mk < j` and `i+(m+1)k >= j`\n",
    "    - Step can be negative"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fa7f15c3-a6ff-44c5-82c0-3c90aca306f9",
   "metadata": {},
   "source": [
    "### Stepped slices\n",
    "- Can similarly give a third argument in a slice -- `l[i:j:k]`\n",
    "- Can omit upper and lower bounds but give a step\n",
    "- `l[::-1]` is the entire list in reverse\n",
    "    - Note that the default lower and upper bound are determined by the step"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8db56dc6-195c-4f71-a079-eed6c9e81036",
   "metadata": {},
   "source": [
    "### Assigning slices\n",
    "- Can assign a list to a slice"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "b8f1b368-6491-47db-a751-f50aa9e909dc",
   "metadata": {},
   "outputs": [],
   "source": [
    "l = list(range(20,30))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "f836827e-5f81-4d08-a0f8-851a0623ca55",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[20, 21, 22, 23, 24, 25, 26, 27, 28, 29]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "f77059e6-6470-4a7b-8fd6-386151facfd8",
   "metadata": {},
   "outputs": [],
   "source": [
    "l[3:6] = [53,54,55]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "82de6823",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[20, 21, 22, 53, 54, 55, 26, 27, 28, 29]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b5edfae4-1905-40cb-9d1d-50adfde2f8e8",
   "metadata": {},
   "source": [
    "- Can contract or expand the slice when reassigning\n",
    "- Indices of values to the right will change"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "c66e57b8-432d-4858-bed1-e9d322e30ebf",
   "metadata": {},
   "outputs": [],
   "source": [
    "l = list(range(20,30))\n",
    "l[3:5] = [53,54,55,63,64,65]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "1112570d-92f2-4491-8dac-b4ddca8f2301",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[20, 21, 22, 53, 54, 55, 63, 64, 65, 25, 26, 27, 28, 29]"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "e1f858b1-0cf4-431e-ac98-4ef8cb32733b",
   "metadata": {},
   "outputs": [],
   "source": [
    "l = list(range(20,30))\n",
    "l[3:5] = []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "a40fbfd2-22ba-48a2-9e0b-3c9cb596e5c0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[20, 21, 22, 25, 26, 27, 28, 29]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1cd4ab6c-71b3-4588-8cb9-28efb57650b4",
   "metadata": {},
   "source": [
    "### Operations on lists\n",
    "- Recall that `+` concatenates two lists\n",
    "- Returns a new list\n",
    "- Original lists are unchanged"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "fc142899-ddb8-47c7-948b-5646b44accb3",
   "metadata": {},
   "outputs": [],
   "source": [
    "l1 = [1,2,3]\n",
    "l2 = [4,5,6]\n",
    "l3 = l1 + l2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "bd7dc9a5-d0c3-4ffa-ac1f-d763a6a7f1a4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 3, 4, 5, 6], [1, 2, 3], [4, 5, 6])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l3, l1, l2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2952a2f9-44e0-451a-a346-de815cbf699e",
   "metadata": {},
   "source": [
    "- A useful invariant about slices\n",
    "- For any list `l`, and any integer `j`, `l == l[:j] + l[j:]`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "22c62563-bccb-4e72-ba93-a677e5da263f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4, 5, 6]"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l3[:-1]+l3[-1:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "1a4bf1ec-9c05-47c7-99e8-e14cb258e08b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4, 5, 6]"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l3[:2]+l3[2:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "71444fdf-97eb-44b4-9faa-a3fe25d4b949",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4, 5, 6]"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l3[:9]+l3[9:]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5ac1ae66-7917-451b-8f0e-562ce21adbf5",
   "metadata": {},
   "source": [
    "### Applying functions to lists\n",
    "- `l.append(v)` is the same as `l = l+[v]`\n",
    "    - Ask the list `l` to append `v` to itself\n",
    "    - `l.append(v)` updates `l` in place\n",
    "    - `l = l+[v]` creates a new list and reassigns the list pointed to by `l`\n",
    "    - Again, we will see the significance of this later"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "7139d381-9939-4e17-8d9c-923bc2710627",
   "metadata": {},
   "outputs": [],
   "source": [
    "l3.append(7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "9ad795a7-ee96-4b6d-90fe-c007cfe61422",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4, 5, 6, 7]"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "0cb6ee50-1619-4dec-873a-3926bc165089",
   "metadata": {},
   "outputs": [],
   "source": [
    "l4 = l3 + [8]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "cc3d6ad6-da8e-4b63-bbbe-9abcd9c887a0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4, 5, 6, 7, 8]"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "a5388cc6-4595-4a79-a50a-670ac584956b",
   "metadata": {},
   "outputs": [],
   "source": [
    "l4 = l4 + [9]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "740b06ea-b2aa-4667-9d7c-2935c6753829",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4, 5, 6, 7, 8, 9]"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l4"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "957db5db-312f-429a-b822-cc58eb137776",
   "metadata": {},
   "source": [
    "- What happens if we reassign a list after an `append()`?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "4ee47fb3-8725-444e-8515-fb3495cded35",
   "metadata": {},
   "outputs": [],
   "source": [
    "l3 = l3.append(8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "96415768-cfac-4229-9894-7bea7d09e680",
   "metadata": {},
   "outputs": [],
   "source": [
    "l3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf9dab32-3ed3-4647-a47f-7dc1452487d3",
   "metadata": {},
   "source": [
    "- It is a mistake to reassign a list after an `append()`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6bc1ac54-f128-4c61-983a-77111c2cb316",
   "metadata": {},
   "source": [
    "- Assignment `v = e` stores return value of `e` in `v`\n",
    "- Return value of `l.append()` is empty"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fb468d09-3a45-4465-abe4-8e3fd97b090e",
   "metadata": {},
   "source": [
    "- Did not say `NameError`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "1238bd2e-3f5a-4559-8568-46f7a731be1a",
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'p' 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[22]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m p\n",
      "\u001b[31mNameError\u001b[39m: name 'p' is not defined"
     ]
    }
   ],
   "source": [
    "p"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cdb8e54a-ca96-4b2a-95c2-0879ed0735a7",
   "metadata": {},
   "source": [
    "- More specifically, `l.append()` returns a special value `None`, that stands for \"no value\", but assigning to `None` is different from not assigning at all\n",
    "- Jupyter notebook does not display `None` as the return value, but try `print(l3.append(8))`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c745bf25-1146-4e9b-9f3e-645e3d5d8290",
   "metadata": {},
   "source": [
    "### Other functions\n",
    "- `l.insert(pos,val)` inserts `val` at position `pos`\n",
    "    - Similar to `l = l[:pos] + [val] + l[pos:]`\n",
    "- `l.extend(newl)` extends `l` with a list of values `newl`\n",
    "    - Similar to `l = l + newl`\n",
    "- Like `l.append(v)`, these update the list in place, do not reassign return value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "cf3246e0-0e2f-4eec-9d2e-b3b915475906",
   "metadata": {},
   "outputs": [],
   "source": [
    "l3 = [1,2,3,4,5,6,7]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "8f4e636e-3fc6-4a3d-a5fd-9540527d80d9",
   "metadata": {},
   "outputs": [],
   "source": [
    "l3.insert(0,0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "96d27977-b85a-405d-b25e-4c833d96cb8e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 2, 3, 4, 5, 6, 7]"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "0df6a902-94c6-40b4-8c2c-a8ef071835ee",
   "metadata": {},
   "outputs": [],
   "source": [
    "l3.extend([8,9,10])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "027dabe6-4f10-4245-b6e6-c2069d3b4df7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f23ba46d-225b-4c6b-ab6c-908a1914b752",
   "metadata": {},
   "source": [
    "### Sorting\n",
    "- `l.sort()` sorts a list in place\n",
    "    - Python allows lists of mixed types\n",
    "    - To sort a list, the values must be of a uniform comparable type"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "69f18f4d-e7b7-46f8-bc35-4a43fd7449b5",
   "metadata": {},
   "outputs": [],
   "source": [
    "l = [1,15,3,7,9,2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "02150f71-b277-433b-b385-7f6f4e53c8b3",
   "metadata": {},
   "outputs": [],
   "source": [
    "l.sort()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "744c7983-b0ee-4fda-b706-5343eb107ca5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 7, 9, 15]"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aedaf261-0697-4536-a7aa-a152a882f2fd",
   "metadata": {},
   "source": [
    "- Python lists can have values of different types"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "ee24fa5f-bf49-482e-beb0-0b7f93c9a569",
   "metadata": {},
   "outputs": [],
   "source": [
    "badl = [1,'CSK',True,7.5]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bf97cd70-2256-44e7-b36c-a17a82eaade4",
   "metadata": {},
   "source": [
    "- However, functions like `sort()` require all values to have compatible types -- in this case, to compare values sensibly"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "1390825b-c99f-40c1-9e6f-3f3bcb943dec",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'<' not supported between instances of 'str' and 'int'",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mTypeError\u001b[39m                                 Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[32]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m badl.sort()\n",
      "\u001b[31mTypeError\u001b[39m: '<' not supported between instances of 'str' and 'int'"
     ]
    }
   ],
   "source": [
    "badl.sort()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "91f6b238-54d9-47d8-81bb-b838304ecdc6",
   "metadata": {},
   "source": [
    "- Can sort values of type `bool`, for example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "05e241ea-eef8-441e-8e15-a56c8e5c8fe8",
   "metadata": {},
   "outputs": [],
   "source": [
    "blist = [True,False,True]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "c293171c-dd4e-4ecd-b21a-a25e60b258db",
   "metadata": {},
   "outputs": [],
   "source": [
    "blist.sort()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "5283b0ae-576e-442c-b806-e757f8defeee",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[False, True, True]"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "blist"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85cb3e38-96a7-4203-976d-c3dc055e0869",
   "metadata": {},
   "source": [
    "- If you want a sorted copy of `l` without disturbing `l`, use `sorted(l)`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "a74af192-668a-49f2-a426-da34a51c8961",
   "metadata": {},
   "outputs": [],
   "source": [
    "l = [15, 1000, 9, 7, 3, 2, 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "b521258a-900b-4029-baf5-b4f373561856",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[15, 1000, 9, 7, 3, 2, 1]"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "d693aac6-89a3-4d7f-810f-804da852e163",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 7, 9, 15, 1000]"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sorted(l)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "222fe345-ff37-48e5-8339-099a353b1f26",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[15, 1000, 9, 7, 3, 2, 1]"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6f68ffdf-f831-462f-a927-5128160d0a06",
   "metadata": {},
   "source": [
    "- Can store a copy of the sorted list in another list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "950b1003-8364-435e-9891-4a23c2e5a890",
   "metadata": {},
   "outputs": [],
   "source": [
    "newl = sorted(l)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "0504e907-1a74-4638-8b1b-6e2927c158c0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 3, 7, 9, 15, 1000], [15, 1000, 9, 7, 3, 2, 1])"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "newl, l"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "84cd61bd-7e12-4a92-887a-ff2f015030a0",
   "metadata": {},
   "source": [
    "- Can we, instead, first copy `l` and sort the copy in place using `sort()`?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "b24ae2d5-9684-4f5f-b530-f1104638a3f7",
   "metadata": {},
   "outputs": [],
   "source": [
    "newl = l"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "866039f6-dabd-42c8-b2b5-b2d9d6071692",
   "metadata": {},
   "outputs": [],
   "source": [
    "newl.sort()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "83db5d74-5fda-4cfe-a98f-1b988fcb00d6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 7, 9, 15, 1000]"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "newl"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "76b35931-5aa3-4f9c-8b30-3bc5793eea1a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 7, 9, 15, 1000]"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "165b960e-9290-4c0b-9c25-b912655e45ee",
   "metadata": {},
   "source": [
    "- Sorting `newl` also sorts `l`\n",
    "- This does not happen with types like `int`\n",
    "- We will investigate this later"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "6fb19b32-d956-4399-90dc-96012b1b846a",
   "metadata": {},
   "outputs": [],
   "source": [
    "y = 7"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "4710d04a-0aee-4d04-bcfb-2828de25d8e5",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "af0f438e-0902-4ce8-a1d5-f347f6d96cf7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(7, 7)"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x, y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "bac0302c-7acf-4bb1-96fd-17d1457495e8",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 17"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "42751cd4-5fb7-4fec-9cfe-e8a783df886e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(17, 7)"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x, y"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ec6b37fd-1af2-476d-804d-0353727adf24",
   "metadata": {},
   "source": [
    "- Many other built-in functions on lists\n",
    "    - `l.reverse()` reverses a list\n",
    "- Look up Python documentation"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b2d1ff58-8e57-4c72-a188-e008e7c2620d",
   "metadata": {},
   "source": [
    "### Tuples\n",
    "- Sequence of values in round brackets - `(v1,v2,...,vk)`\n",
    "- Typically values are not of a uniform type\n",
    "    - Collect together different attributes of an item\n",
    "    - Row in a table; each column is an attribute"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "d969e37e-b4e4-4239-9313-4ef4149b3c16",
   "metadata": {},
   "outputs": [],
   "source": [
    "t = (\"Mexico City\",\"MEX\",\"RSA\",2,0,0,0,1.84,0.52)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "959d64f6-cd8f-4418-a6de-704b459de16e",
   "metadata": {},
   "source": [
    "- Positional indexing, slicing like other sequences"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "f2832007-d080-4992-af70-5e1e6e075aff",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('RSA', 0.52)"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t[2],t[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "041c3bda-a992-4f2b-9aee-e2dc7de62521",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('MEX', 'RSA', 2)"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t[1:4]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c3667d30-26a3-4d4a-8dc1-87564af8737b",
   "metadata": {},
   "source": [
    "- Iterate over a tuple\n",
    "    - `print()` prints its arguments --- either a message (string) or value of a variable"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "44f8baa0-6627-4a00-b49c-4db3a126f359",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x is Mexico City , to repeat Mexico City\n",
      "x is MEX , to repeat MEX\n",
      "x is RSA , to repeat RSA\n",
      "x is 2 , to repeat 2\n",
      "x is 0 , to repeat 0\n",
      "x is 0 , to repeat 0\n",
      "x is 0 , to repeat 0\n",
      "x is 1.84 , to repeat 1.84\n",
      "x is 0.52 , to repeat 0.52\n"
     ]
    }
   ],
   "source": [
    "for x in t:\n",
    "    print(\"x is\", x, \", to repeat\", x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "44d20a92-d9d1-4ebf-8888-97ff99bbe4f3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(False, True)"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'BRA' in t, 'MEX' in t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "259d6eb8-2d40-47a3-b666-1a6059fc6992",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('Mexico City', 'MEX', 'RSA', 2, 0, 0, 0, 1.84, 0.52)\n"
     ]
    }
   ],
   "source": [
    "print(t)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "67388361-4a88-419c-9f40-c044bcbfc5cc",
   "metadata": {},
   "source": [
    "- Unlike lists, cannot update a component of a tuple"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "645d0ae7-870c-4493-ab9f-0e13520be38a",
   "metadata": {},
   "outputs": [],
   "source": [
    "t = (\"Mexico City\",\"MEX\",\"RSA\",2,0,0,0,1.84,0.52)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "ceb057a1-23b0-4f72-87b7-242b17f70485",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'tuple' object does not support item assignment",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mTypeError\u001b[39m                                 Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[58]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m t[\u001b[32m2\u001b[39m] = \u001b[33m'BRA'\u001b[39m\n",
      "\u001b[31mTypeError\u001b[39m: 'tuple' object does not support item assignment"
     ]
    }
   ],
   "source": [
    "t[2] = 'BRA'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "632b6a51-fc87-4acd-881b-fca230c38ac2",
   "metadata": {},
   "source": [
    "- Can concatenate tuples using `+`\n",
    "    - Update a tuple by assembling a new tuple\n",
    "- Be careful, insert a comma to indicate a singleton tuple: `(v,)` vs `(v)`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "id": "566d18ff-cffc-489a-b067-8f05db5ed89b",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "can only concatenate tuple (not \"str\") to tuple",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mTypeError\u001b[39m                                 Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[59]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m u = t[\u001b[32m0\u001b[39m:\u001b[32m2\u001b[39m]+(\u001b[33m'BRA'\u001b[39m)+t[\u001b[32m3\u001b[39m:]  \u001b[38;5;66;03m# No difference between 'BRA' and ('BRA')\u001b[39;00m\n",
      "\u001b[31mTypeError\u001b[39m: can only concatenate tuple (not \"str\") to tuple"
     ]
    }
   ],
   "source": [
    "u = t[0:2]+('BRA')+t[3:]  # No difference between 'BRA' and ('BRA')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "ce6d4189",
   "metadata": {},
   "outputs": [],
   "source": [
    "u = t[0:2]+('BRA',)+t[3:]  # ('BRA',) is recognized a singleton tuple"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "id": "9d758bde-80e6-4065-8976-d58b858c5b43",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('Mexico City', 'MEX', 'BRA', 2, 0, 0, 0, 1.84, 0.52)"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "u"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1b555caf-5720-41d6-be4f-1d0e5e7ce30e",
   "metadata": {},
   "source": [
    "- Can use `list()` to convert a tuple to a list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "id": "5580f876-a0bd-47d4-b8dd-4b38aecfec6a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Mexico City', 'MEX', 'RSA', 2, 0, 0, 0, 1.84, 0.52]"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "id": "449d41cb-dc37-45b8-ac5e-ecf025b3bed7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tuple"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(u)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "id": "422a0df2-a7aa-4e4f-8dd4-2f2faa7860e9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "list"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(list(u))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f819a994-8131-45d2-b50f-490659860ab5",
   "metadata": {},
   "source": [
    "- In general `list()` works provided its argument is a sequence"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "id": "a9173066-b456-4623-a783-3a400922e0d2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 2, 3, 4]"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(range(5))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "375ff5a6-cd06-49ef-9aa1-e324ee77daa3",
   "metadata": {},
   "source": [
    "- If the argument is not a sequence, `list()` generates an error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "id": "4489aa3f-5a8d-4513-af34-80703135aa2e",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'int' object is not iterable",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mTypeError\u001b[39m                                 Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[66]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m list(\u001b[32m7\u001b[39m)\n",
      "\u001b[31mTypeError\u001b[39m: 'int' object is not iterable"
     ]
    }
   ],
   "source": [
    "list(7)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cbfae2cf-37e5-43be-ae9f-4114928f7adb",
   "metadata": {},
   "source": [
    "- Any type name can be used as a function to convert to that type\n",
    "- However, the argument needs to have a sensible interpretation in the target type"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "90493796-ab83-4621-a4bf-a72feb5b1ba0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "7"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "int(7.5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "id": "5e706cdb-6229-47f8-8fea-5e5a29f93b58",
   "metadata": {},
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "invalid literal for int() with base 10: 'B'",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mValueError\u001b[39m                                Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[68]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m int(\u001b[33m\"B\"\u001b[39m)\n",
      "\u001b[31mValueError\u001b[39m: invalid literal for int() with base 10: 'B'"
     ]
    }
   ],
   "source": [
    "int(\"B\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bcb29ae8-30f2-49f7-934e-4f5fd0098fe7",
   "metadata": {},
   "source": [
    "- Notice the error specifically refers to `base 10`\n",
    "- `int()` takes an optional second argument, specifying the base. In base 16, the values 10,11,...,15 are denoted A,B,...,F"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "id": "0b0f45b2-76da-4953-a466-7934eba1d299",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "11"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "int(\"B\",16)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bc5e737c-5cb2-4e89-a2b2-bdcaca8041a3",
   "metadata": {},
   "source": [
    "- Can assign a tuple of variables in one shot\n",
    "    - Useful for initialising multiple quantities\n",
    "    - In `nprimes()` we started with `primelist = []` and `p = 2`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "id": "2d004d9e-36db-404a-9ac2-718f563aed23",
   "metadata": {},
   "outputs": [],
   "source": [
    "(primelist,p) = ([],2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "id": "cd70598e-83f7-476a-a236-1c76502388bc",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Equivalent to\n",
    "primelist = []\n",
    "p = 2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e723758d-3712-4b81-a5e3-5f56ebd1624b",
   "metadata": {},
   "source": [
    "- `(x,y) = (y,x)` swaps the values of `x` and `y`\n",
    "    - All values on rhs are old values\n",
    "    - All values on lhs are new assignments\n",
    "    - Cannot be done sequentially\n",
    "        - Not equivalent to `x = y` followed by `y = x` or vice versa\n",
    "- Normally, swap requires a temporary variable\n",
    "```\n",
    "t = y\n",
    "y = x\n",
    "x = t\n",
    "```\n",
    "- Imagine exchanging the contents of a glass of juice and a glass of milk\n",
    "    - Need a third empty glass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "id": "74bab3af-dd9d-4e07-b110-f3b470fadfee",
   "metadata": {},
   "outputs": [],
   "source": [
    "(x,y) = (5,[])\n",
    "(x,y) = (y,x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "id": "6832c415-13a2-41f8-a17b-24e1666b7c36",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([], 5)"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x,y"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eac658e2-7973-4c4f-bcf8-95105e41f2a9",
   "metadata": {},
   "source": [
    "- When we say `x,y` we mean `(x,y)` --- brackets may be omitted\n",
    "- Python inserts them to display the value to us"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "id": "dd861b45-d9f6-4d23-aa5b-9224f153dacd",
   "metadata": {},
   "outputs": [],
   "source": [
    "x,y = 5,[]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "id": "fd074383-6256-45ce-86cc-8158ec311379",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(5, [])"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x,y"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6b097078-2da4-4f18-9f0e-ff16d591e9bb",
   "metadata": {},
   "source": [
    "### Dictionaries\n",
    "- A list is a collection indexed by position \n",
    "- A list can be thought of as a function $f: \\{0,1,\\ldots,n-1\\} \\to \\{v_0,v_1,\\ldots,v_{n-1}\\}$\n",
    "  - A list maps positions to values\n",
    "- Generalize this to a function $f: \\{k_0,k_1,\\ldots,k_{n-1}\\} \\to \\{v_0,v_1,\\ldots,v_{n-1}\\}$\n",
    "  - Instead of positions, index by an abstract *key*\n",
    "- **dictionary**: maps keys, rather than positions, to values\n",
    "- Notation:\n",
    "  - `d = {k1:v1, k2:v2}`, enumerate a dictionary explicitly\n",
    "  - `d[k1]`, value in dictionary `d1` corresponding to key `k1`\n",
    "  - `{}`, empty dictionary (`[]` for lists, `()` for tuples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "id": "d8fc9e79-badf-4882-ac76-f1f3f8f377fd",
   "metadata": {},
   "outputs": [],
   "source": [
    "myd = {'a':1,'b':17,'c':0}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "id": "bef0ef37-d2ea-4b0d-9a69-b466d9191575",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "17"
      ]
     },
     "execution_count": 77,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "myd['b']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "id": "7fa68be6-5640-4943-b725-04d403fae808",
   "metadata": {},
   "outputs": [
    {
     "ename": "KeyError",
     "evalue": "'d'",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mKeyError\u001b[39m                                  Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[78]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m myd[\u001b[33m'd'\u001b[39m]  \u001b[38;5;66;03m# Invalid key\u001b[39;00m\n",
      "\u001b[31mKeyError\u001b[39m: 'd'"
     ]
    }
   ],
   "source": [
    "myd['d']  # Invalid key"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "id": "bf5a300b-7f80-4942-a030-b856cee1b545",
   "metadata": {},
   "outputs": [],
   "source": [
    "myd['d'] = 17"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "id": "ed814d6f-c80f-48b1-9840-b1137544108f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "17"
      ]
     },
     "execution_count": 80,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "myd['d']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "id": "8084e51e-ee81-43fd-8084-d4be7e856aa4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a': 1, 'b': 17, 'c': 0, 'd': 17}"
      ]
     },
     "execution_count": 81,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "myd"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d45aada7-b69f-45a8-9476-71f22e9e5039",
   "metadata": {},
   "source": [
    "- An assignment `d[k] = v` serves two purposes\n",
    "    - If there is no key `k`, create the key and assign it the value `v`\n",
    "    - If there is already a key `k`, replace its current value by `v`\n",
    "- In a list, we cannot create a value at a new position through an assignment\n",
    "    - If `l` is `[0,1,2,3]`, `l[4] = 4` generate `IndexError`\n",
    "    - If `myd = {'a':1,'b':17,'c':0}`, `myd['d'] = 19` extends `d` with a new key-value pair"
   ]
  }
 ],
 "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
}
