{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "6b4fce18-128e-441d-9040-7d738b1ac1c8",
   "metadata": {},
   "source": [
    "## PDSP 2026, Lecture 08, 3 September 2026"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "98f9ed19-7917-4a05-9735-936b1e5383c5",
   "metadata": {},
   "source": [
    "### Strings\n",
    "- Also sequences, of characters\n",
    "- String values can be enclosed in single or double quotes\n",
    "    - `'Chennai'` or `\"Chennai\"`\n",
    "- Allows a value that has a quote to be easily embedded\n",
    "    - `\"Fermat's Last Theorem\"`\n",
    "    - `'He said, \"Thank you!\"`\n",
    "- If you need to use both single and double quotes inside the string, use a triple quote!\n",
    "    - `'''He said, \"That's great!\"'''`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "411eca0c-7532-4077-92e1-f3253f7f3299",
   "metadata": {},
   "outputs": [],
   "source": [
    "s = '''He said, \"That's great!\"'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "2fec1aac-a6ef-4eb1-acd7-559c2498e281",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'He said, \"That\\'s great!\"'"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "54db6aa5-ced8-4d70-a93a-01bc2097bc05",
   "metadata": {},
   "source": [
    "- Python prefers to render strings using single quote\n",
    "- Embedded quotes are \"escaped\" using `\\` to remove their special meaning"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fdd6aca3-76f2-4d81-b26b-bcb822fccd67",
   "metadata": {},
   "source": [
    "- Like lists and tuples, can access elements of a string by position, or by slices"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "fdc7dd9d-704d-45d0-af41-ffd917499dad",
   "metadata": {},
   "outputs": [],
   "source": [
    "s = \"hello\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "65b2cb63-3ef3-46f8-a69f-964028cd43dc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'e'"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "53d57f02-fb50-4608-a767-e2a3edf3496a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'ll'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s[2:4]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3486b0c1-5cda-49e4-ae40-5132f6162d0f",
   "metadata": {},
   "source": [
    "- Some languages have a separate type `char` for a single character\n",
    "    - A string is then a sequence of `char`\n",
    "- In Python, there is only the string type `str`\n",
    "    - A single character is the same as a string of length 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "6da97fea-5521-478a-9777-8c7e660befbd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s[1] == \"e\"  # Logically speaking, s[1] is a single character"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "946b98fb-708a-4c5f-9afd-f60bad35be93",
   "metadata": {},
   "source": [
    "- Concatenate strings using `+`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "9257524a-a5fb-4bf1-9665-7e506764f596",
   "metadata": {},
   "outputs": [],
   "source": [
    "s = \"hello\"\n",
    "t = \"there\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "84a43675-65a9-45ec-9af2-f4eabb6604be",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('hellothere', 'hello', 'there')"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s+t, s, t"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "13971d5f-2e04-4682-ae05-b295fa9b7ee7",
   "metadata": {},
   "source": [
    "- Notice that `s+t` does not have any character between `s` and `t`\n",
    "- If we want a separator, we need to add it ourselves"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "fe6ccb87-3e98-4c55-9d33-18e941ae0496",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'hello there'"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s + \" \" + t"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "69192fd4-e7b7-483f-827c-d3e7fd276e7e",
   "metadata": {},
   "source": [
    "- Like tuples, cannot update parts of a string directly"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "7c952f0c-f419-4890-8fb5-00fe5c6d0378",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'str' 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[10]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m s[\u001b[32m3\u001b[39m] = \u001b[33m\"p\"\u001b[39m\n",
      "\u001b[31mTypeError\u001b[39m: 'str' object does not support item assignment"
     ]
    }
   ],
   "source": [
    "s[3] = \"p\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "338ec8d1-d566-4077-ae16-36fdea673be2",
   "metadata": {},
   "source": [
    "- Instead, assemble a new string from the old one"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "6abff667-6eb3-4bdf-a337-26c91345036f",
   "metadata": {},
   "outputs": [],
   "source": [
    "s = s[0:3] + \"p\" + s[4:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "9b1ef9ef-8b3e-40b7-9320-2efda1beca50",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'helpo'"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "b861cac0-7b24-40b0-b41f-7a4c69936d9f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'helo'"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s[0:3] + s[4]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b8bd9ce5-8478-462d-ad3a-2752a0c8b594",
   "metadata": {},
   "source": [
    "- Notice that `s[0:3]`, which is a string, is compatible with `s[4]`, which is a single item in the string\n",
    "- This is different from lists and tuples, where the items in the list are one level \"lower\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "319b7b60-2f6a-405a-bf4f-74e6c4db91a3",
   "metadata": {},
   "outputs": [],
   "source": [
    "l = [1,2,3,4,5]\n",
    "t = (1,2,3,4,5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "82d0aa1a-9b21-4fa7-9fa4-c78c1b31b39d",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "can only concatenate list (not \"int\") to list",
     "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[15]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m l[\u001b[32m0\u001b[39m:\u001b[32m3\u001b[39m] + l[\u001b[32m4\u001b[39m]\n",
      "\u001b[31mTypeError\u001b[39m: can only concatenate list (not \"int\") to list"
     ]
    }
   ],
   "source": [
    "l[0:3] + l[4]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "57854273-ccc3-44f1-b211-fc1749299cb5",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "can only concatenate tuple (not \"int\") 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[16]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m t[\u001b[32m0\u001b[39m:\u001b[32m3\u001b[39m] + t[\u001b[32m4\u001b[39m]\n",
      "\u001b[31mTypeError\u001b[39m: can only concatenate tuple (not \"int\") to tuple"
     ]
    }
   ],
   "source": [
    "t[0:3] + t[4]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "82cf3e41-5d0c-45dc-8939-33a76d726216",
   "metadata": {},
   "source": [
    "- Can iterate over strings and check membership, like lists\n",
    "- For iteration, no distinction between a string `\"xyz\"` and the list `[\"x\",\"y\",\"z\"]`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "4f350fb1-467e-4858-a919-fb9bb8c427e2",
   "metadata": {},
   "outputs": [],
   "source": [
    "def vowel(c):\n",
    "    return(c in \"aeiou\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "26f92d73-cb76-43bd-9340-9a780a10a5f3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(True, False)"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vowel(\"a\"),vowel(\"b\"),"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8829f2aa-09ee-411a-8d6d-1ab0db095a74",
   "metadata": {},
   "source": [
    "- For strings, `x in s` is interpreted as substring membership"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "47441292-189e-4670-a9e1-43cfd8db0a21",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(True, False, True)"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vowel(\"ae\"),vowel(\"ai\"),vowel(\"io\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf5516cc-9756-4836-9085-84eff0573b12",
   "metadata": {},
   "source": [
    "- This would not work for lists or tuples\n",
    "- For instance `[1,2] in [1,2,3]` would return `False`\n",
    "- But `[1,2] in [[1,2],[2,3]]` would return `True`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "e96bbf1c-e714-4bb2-82af-9b1ae826175b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(False, True)"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[1,2] in [1,2,3], [1,2] in [[1,2],[2,3]]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0237ac2e-1bcc-484b-bfe1-3eb92f1eb537",
   "metadata": {},
   "source": [
    "- Standard example of filtered iteration"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "ee69d477-ef7f-40c2-8e7d-2bc6f3c29e74",
   "metadata": {},
   "outputs": [],
   "source": [
    "def countvowels(s):\n",
    "    count = 0\n",
    "    for c in s:\n",
    "        if vowel(c):\n",
    "            count = count+1\n",
    "    return(count)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "d12fd3db-af41-49fb-9720-834e23c287c2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "countvowels(\"hello\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fbe4dee8-f07a-418b-8546-347258b0f8eb",
   "metadata": {},
   "source": [
    "- `x in s` expects `x` to be a string if `s` is a string"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "83f5a864-6b3f-45dc-8968-3f1127171dd1",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'in <string>' requires string as left operand, not 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[23]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m vowel(\u001b[32m7\u001b[39m)\n",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[17]\u001b[39m\u001b[32m, line 2\u001b[39m, in \u001b[36mvowel\u001b[39m\u001b[34m(c)\u001b[39m\n\u001b[32m      1\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m vowel(c):\n\u001b[32m----> \u001b[39m\u001b[32m2\u001b[39m     \u001b[38;5;28;01mreturn\u001b[39;00m(c \u001b[38;5;28;01min\u001b[39;00m \u001b[33m\"aeiou\"\u001b[39m)\n",
      "\u001b[31mTypeError\u001b[39m: 'in <string>' requires string as left operand, not int"
     ]
    }
   ],
   "source": [
    "vowel(7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "3dacb31c-f8e5-4302-8fe7-c0c1c5685484",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vowel(\"7\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "f3d24b16-7aa6-4ece-9e96-fa3d4a53d50a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vowel(\"there\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f22d8e37-9215-4038-8b30-7d5439a19841",
   "metadata": {},
   "source": [
    "- We have seen that `list()` and `int()` can be use to convert values from one type to another\n",
    "- Likewise `str()` converts its argument to a string\n",
    "    - Almost any value converts sensibly into a \"readable\" representation\n",
    "    - `print(v)` implicitly converts `v` to `str(v)` to display on screen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "67d55c3c-bad4-404c-b650-8616ab24c5e9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'[1, 2, 3]'"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "str([1,2,3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "1ac30287-6d74-4e30-a7cb-e062f270bb22",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'77'"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "str(77)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "d0ebff44-da18-4584-9e41-78103bf72330",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'[1, 2, 3]'"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "str([1,  2,3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "7f01d396-52ff-4f07-a4c5-f031b2db7389",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3]\n"
     ]
    }
   ],
   "source": [
    "print(str([1,  2,3]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "b5d5b1c9-e52c-44e1-963f-59bc2d363752",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3]\n"
     ]
    }
   ],
   "source": [
    "print([1,2,3]) # via str([1,2,3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "65c3d687-d760-4415-ae5f-ff99325cafaa",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'range(0, 5)'"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "str(range(5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "13c9a0b5-8aa1-425e-be02-46ae9a969cdc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'n'"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = str(range(5))\n",
    "s[2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "302c0140-3c35-4e34-a764-2e7d91991908",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'range(0, 5)'"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "str(range(0,5,1))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6775a477-b1a7-44d0-b8d9-50bb20328568",
   "metadata": {},
   "source": [
    "- Can convert a string to a number if the contents can be intepreted sensibly"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "2decd87e-dde9-421a-a7a7-1250a52c2597",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "77"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "int('77')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "9da617d1-e00d-4a19-9529-1b266ac03eb5",
   "metadata": {},
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "invalid literal for int() with base 10: 'hello'",
     "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[35]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m int(\u001b[33m'hello'\u001b[39m)\n",
      "\u001b[31mValueError\u001b[39m: invalid literal for int() with base 10: 'hello'"
     ]
    }
   ],
   "source": [
    "int('hello')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "11dea25b-8aa3-41b6-b54e-ca6c1cf9f0f0",
   "metadata": {},
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "invalid literal for int() with base 10: '77.5'",
     "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[36]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m int(\u001b[33m'77.5'\u001b[39m)  \u001b[38;5;66;03m# 77.5 is a number, but not an int\u001b[39;00m\n",
      "\u001b[31mValueError\u001b[39m: invalid literal for int() with base 10: '77.5'"
     ]
    }
   ],
   "source": [
    "int('77.5')  # 77.5 is a number, but not an int"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "e4b6d1f8-be5f-4129-9044-0e840559e07c",
   "metadata": {},
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "invalid literal for int() with base 10: '77.0'",
     "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[37]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m int(\u001b[33m'77.0'\u001b[39m)  \u001b[38;5;66;03m# Even if the number is semantically an int, the decimal point disallows conversion\u001b[39;00m\n",
      "\u001b[31mValueError\u001b[39m: invalid literal for int() with base 10: '77.0'"
     ]
    }
   ],
   "source": [
    "int('77.0')  # Even if the number is semantically an int, the decimal point disallows conversion"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "a3636dde-78eb-45e7-86e0-b9baca41bb28",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "77.5"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "float('77.5')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "8d6c6688-6ece-4c45-bf0c-77db42dab676",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "77.0"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "float('77')  # string representing an int can be converted to a float"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e8b2cc1b-665a-4f1b-b646-c5059a192c32",
   "metadata": {},
   "source": [
    "## Dictionary keys"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3cc452b1-6bd2-479b-89df-218749547931",
   "metadata": {},
   "source": [
    "- Dictionary keys must be *immutable*\n",
    "- Related to how dictionaries are stored\n",
    "    - Location of value is obtained by applying hash function to the key\n",
    "    - If they key is allowed to change, hash function will map to another location"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "23375aa2-d9ef-494e-aa1a-1f74b0e24a64",
   "metadata": {},
   "outputs": [],
   "source": [
    "d = {}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "87860dc0-ec37-4ac6-80f4-97dae0096e64",
   "metadata": {},
   "outputs": [],
   "source": [
    "d[1] = 7"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "ecc7ec01-8181-43a1-874a-01bd0c2af35b",
   "metadata": {},
   "outputs": [],
   "source": [
    "d[8.5] = 8"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "c6e17be5-7b4a-4e53-bc85-b7095c031e72",
   "metadata": {},
   "outputs": [],
   "source": [
    "d[\"MEX\"] = \"Arlington\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "93738487-51c2-41ac-bdd8-bc05864a6ebb",
   "metadata": {},
   "outputs": [],
   "source": [
    "d[(3,4)] = 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "dbd206b2-59f6-4fa4-aa6d-56b970ef38cd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1: 7, 8.5: 8, 'MEX': 'Arlington', (3, 4): 5}"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "b1a04f95-626b-4ad9-b416-db70f7850bd0",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "unhashable type: 'list'",
     "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[46]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m d[[\u001b[32m6\u001b[39m,\u001b[32m8\u001b[39m]] = \u001b[32m10\u001b[39m\n",
      "\u001b[31mTypeError\u001b[39m: unhashable type: 'list'"
     ]
    }
   ],
   "source": [
    "d[[6,8]] = 10"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "703e27fa-aba1-44c5-8c04-9e79ee80310a",
   "metadata": {},
   "source": [
    "- Key can be `int`, `float`, `bool`, `str`, tuple\n",
    "- Cannot use a list or a dictionary as a key"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "343843aa-5a0b-43ef-a08c-60983a2ad97c",
   "metadata": {},
   "source": [
    "## Map and filter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "90dd963d-bf0a-4fa5-963d-1f79a418243d",
   "metadata": {},
   "outputs": [],
   "source": [
    "matchlist = [\n",
    "  (\"Mexico City\",\"MEX\",\"RSA\",2,0,0,0,1.84,0.52),\n",
    "  (\"Zapopan\",\"KOR\",\"CZE\",2,1,0,0,1.45,1.12),\n",
    "  (\"Toronto\",\"CAN\",\"BIH\",1,1,0,0,1.35,0.98),\n",
    "  (\"Inglewood\",\"USA\",\"PAR\",4,1,0,0,2.76,0.88),\n",
    "  (\"Foxborough\",\"QAT\",\"SUI\",1,1,0,0,0.78,1.54),\n",
    "  (\"East Rutherford\",\"BRA\",\"MAR\",1,1,0,0,1.62,1.1),\n",
    "  (\"Philadelphia\",\"HAI\",\"SCO\",0,1,0,0,1.25,0.65),\n",
    "  (\"Seattle\",\"AUS\",\"TUR\",2,0,0,0,1.48,0.72),\n",
    "  (\"Atlanta\",\"GER\",\"CUW\",7,1,0,0,4.82,0.44),\n",
    "  (\"Santa Clara\",\"NED\",\"JPN\",2,2,0,0,1.95,1.82),\n",
    "  (\"Houston\",\"CIV\",\"ECU\",1,0,0,0,1.1,0.95),\n",
    "  (\"Kansas City\",\"SWE\",\"TUN\",5,1,0,0,3.12,0.78),\n",
    "  (\"Miami Gardens\",\"ESP\",\"CPV\",0,0,0,0,2.15,0.35),\n",
    "  (\"Arlington\",\"BEL\",\"EGY\",1,1,0,0,1.58,1.12),\n",
    "  (\"Guadalupe\",\"KSA\",\"URU\",1,1,0,0,0.85,1.76),\n",
    "  (\"Vancouver\",\"IRN\",\"NZL\",2,2,0,0,1.88,1.2),\n",
    "  (\"East Rutherford\",\"FRA\",\"SEN\",3,1,0,0,2.44,1.05),\n",
    "  (\"Foxborough\",\"IRQ\",\"NOR\",1,4,0,0,0.68,2.85),\n",
    "  (\"Inglewood\",\"ARG\",\"ALG\",3,0,0,0,2.65,0.42),\n",
    "  (\"Santa Clara\",\"AUT\",\"JOR\",3,1,0,0,1.98,0.88),\n",
    "  (\"Atlanta\",\"POR\",\"COD\",1,1,0,0,1.78,1.15),\n",
    "  (\"Miami Gardens\",\"ENG\",\"CRO\",4,2,0,0,2.92,1.64),\n",
    "  (\"Houston\",\"GHA\",\"PAN\",1,0,0,0,1.3,0.75),\n",
    "  (\"Seattle\",\"UZB\",\"COL\",1,3,0,0,0.95,2.1),\n",
    "  (\"Atlanta\",\"MEX\",\"KOR\",1,0,0,0,1.62,0.58),\n",
    "  (\"Inglewood\",\"CZE\",\"RSA\",1,1,0,0,1.35,1.15),\n",
    "  (\"Vancouver\",\"CAN\",\"QAT\",6,0,0,0,3.82,0.22),\n",
    "  (\"Mexico City\",\"SUI\",\"BIH\",4,1,0,0,2.45,0.88),\n",
    "  (\"East Rutherford\",\"BRA\",\"HAI\",3,0,0,0,1.16,0.9),\n",
    "  (\"Arlington\",\"SCO\",\"MAR\",0,1,0,0,0.97,0.54),\n",
    "  (\"Toronto\",\"USA\",\"AUS\",2,0,0,0,1.21,0.32),\n",
    "  (\"Guadalupe\",\"TUR\",\"PAR\",0,1,0,0,0.4,0.3),\n",
    "  (\"Foxborough\",\"GER\",\"CIV\",2,1,0,0,1.85,0.72),\n",
    "  (\"Kansas City\",\"ECU\",\"CUW\",0,0,0,0,1.92,0.08),\n",
    "  (\"Philadelphia\",\"NED\",\"SWE\",5,1,0,0,3.45,0.88),\n",
    "  (\"Seattle\",\"TUN\",\"JPN\",0,4,0,0,0.35,3.12),\n",
    "  (\"Houston\",\"BEL\",\"IRN\",0,0,0,0,1.45,0.62),\n",
    "  (\"Miami Gardens\",\"NZL\",\"EGY\",1,3,0,0,0.55,2.15),\n",
    "  (\"Santa Clara\",\"ESP\",\"KSA\",4,0,0,0,3.28,0.25),\n",
    "  (\"East Rutherford\",\"URU\",\"CPV\",2,2,0,0,1.65,1.1),\n",
    "  (\"Arlington\",\"FRA\",\"IRQ\",3,0,0,0,2.21,0.45),\n",
    "  (\"Toronto\",\"NOR\",\"SEN\",3,2,0,0,1.95,1.48),\n",
    "  (\"Guadalupe\",\"ARG\",\"AUT\",2,0,0,0,1.78,0.55),\n",
    "  (\"Foxborough\",\"JOR\",\"ALG\",1,2,0,0,0.88,1.92),\n",
    "  (\"Kansas City\",\"POR\",\"UZB\",5,0,0,0,3.54,0.42),\n",
    "  (\"Philadelphia\",\"COL\",\"COD\",1,0,0,0,1.62,0.58),\n",
    "  (\"Seattle\",\"ENG\",\"GHA\",0,0,0,0,1.12,0.89),\n",
    "  (\"Mexico City\",\"PAN\",\"CRO\",0,1,0,0,0.42,1.48),\n",
    "  (\"Mexico City\",\"CZE\",\"MEX\",0,3,0,0,1.1,1.27),\n",
    "  (\"Zapopan\",\"RSA\",\"KOR\",1,0,0,0,1.26,1.39),\n",
    "  (\"Vancouver\",\"SUI\",\"CAN\",2,1,0,0,0.71,1.35),\n",
    "  (\"Toronto\",\"BIH\",\"QAT\",3,1,0,0,1.48,0.95),\n",
    "  (\"East Rutherford\",\"SCO\",\"BRA\",0,3,0,0,0.45,2.18),\n",
    "  (\"Foxborough\",\"MAR\",\"HAI\",4,2,0,0,2.35,1.12),\n",
    "  (\"Inglewood\",\"TUR\",\"USA\",3,2,0,0,1.62,1.45),\n",
    "  (\"Santa Clara\",\"PAR\",\"AUS\",0,0,0,0,0.55,0.48),\n",
    "  (\"Atlanta\",\"ECU\",\"GER\",2,1,0,0,1.28,1.55),\n",
    "  (\"Houston\",\"CUW\",\"CIV\",0,2,0,0,0.32,1.68),\n",
    "  (\"Kansas City\",\"TUN\",\"NED\",1,3,0,0,0.62,2.15),\n",
    "  (\"Seattle\",\"JPN\",\"SWE\",1,1,0,0,1.12,0.95),\n",
    "  (\"Arlington\",\"NZL\",\"BEL\",1,5,0,0,0.48,3.25),\n",
    "  (\"Guadalupe\",\"EGY\",\"IRN\",1,1,0,0,0.85,0.92),\n",
    "  (\"Miami Gardens\",\"URU\",\"ESP\",0,1,0,0,0.78,1.35),\n",
    "  (\"Philadelphia\",\"CPV\",\"KSA\",0,0,0,0,0.42,0.38),\n",
    "  (\"Foxborough\",\"NOR\",\"FRA\",1,4,0,0,1.3,0.96),\n",
    "  (\"East Rutherford\",\"SEN\",\"IRQ\",5,0,0,0,3.01,0.14),\n",
    "  (\"Santa Clara\",\"JOR\",\"ARG\",1,3,0,0,0.76,2.13),\n",
    "  (\"Inglewood\",\"ALG\",\"AUT\",3,3,0,0,1.62,1.44),\n",
    "  (\"Miami Gardens\",\"COL\",\"POR\",0,0,0,0,1.62,0.73),\n",
    "  (\"Atlanta\",\"COD\",\"UZB\",3,1,0,0,2.35,0.2),\n",
    "  (\"East Rutherford\",\"PAN\",\"ENG\",0,2,0,0,0.69,1.39),\n",
    "  (\"Philadelphia\",\"CRO\",\"GHA\",2,1,0,0,0.42,0.74),\n",
    "  (\"Inglewood\",\"RSA\",\"CAN\",0,1,0,0,0.13,1.32),\n",
    "  (\"Houston\",\"BRA\",\"JPN\",2,1,0,0,1.69,0.23),\n",
    "  (\"Foxborough\",\"GER\",\"PAR\",1,1,3,4,0.72,0.42),\n",
    "  (\"Guadalupe\",\"NED\",\"MAR\",1,1,2,3,0.23,1.4),\n",
    "  (\"Arlington\",\"CIV\",\"NOR\",1,2,0,0,1.15,2.02),\n",
    "  (\"East Rutherford\",\"FRA\",\"SWE\",3,0,0,0,3.17,0.67),\n",
    "  (\"Mexico City\",\"MEX\",\"ECU\",2,0,0,0,1.02,0.73),\n",
    "  (\"Atlanta\",\"ENG\",\"COD\",2,1,0,0,2.04,0.76),\n",
    "  (\"Seattle\",\"BEL\",\"SEN\",3,2,0,0,1.74,3.58),\n",
    "  (\"Santa Clara\",\"USA\",\"BIH\",2,0,0,0,0.92,0.25),\n",
    "  (\"Inglewood\",\"ESP\",\"AUT\",3,0,0,0,2.84,0.32),\n",
    "  (\"Toronto\",\"POR\",\"CRO\",2,1,0,0,2.18,1.34),\n",
    "  (\"Vancouver\",\"SUI\",\"ALG\",2,0,0,0,2.52,0.73),\n",
    "  (\"Arlington\",\"AUS\",\"EGY\",1,1,2,4,0.87,1.36),\n",
    "  (\"Miami Gardens\",\"ARG\",\"CPV\",3,2,0,0,2.16,0.46),\n",
    "  (\"Kansas City\",\"COL\",\"GHA\",1,0,0,0,2.19,0.26),\n",
    "  (\"Philadelphia\",\"PAR\",\"FRA\",0,1,0,0,0.3,1.8),\n",
    "  (\"Houston\",\"CAN\",\"MAR\",0,3,0,0,0.8,1.2),\n",
    "  (\"Arlington\",\"BRA\",\"NOR\",1,2,0,0,2.61,1.05),\n",
    "  (\"Mexico City\",\"MEX\",\"ENG\",2,3,0,0,1.88,1.61),\n",
    "  (\"Miami Gardens\",\"POR\",\"ESP\",0,1,0,0,0.63,1.69),\n",
    "  (\"Santa Clara\",\"USA\",\"BEL\",1,4,0,0,0.67,2.15),\n",
    "  (\"Kansas City\",\"ARG\",\"EGY\",3,2,0,0,2.12,1.54),\n",
    "  (\"Seattle\",\"SUI\",\"COL\",0,0,4,3,1.15,1.46),\n",
    "  (\"Foxborough\",\"FRA\",\"MAR\",2,0,0,0,3.1,0.13),\n",
    "  (\"Inglewood\",\"ESP\",\"BEL\",2,1,0,0,2.08,0.37),\n",
    "  (\"Miami Gardens\",\"NOR\",\"ENG\",1,2,0,0,0.77,0.96),\n",
    "  (\"Kansas City\",\"ARG\",\"SUI\",3,1,0,0,2.0,0.53),\n",
    "  (\"Arlington\",\"FRA\",\"ESP\",0,2,0,0,0.3,1.63),\n",
    "  (\"Atlanta\",\"ENG\",\"ARG\",1,2,0,0,0.54,1.80),\n",
    "  (\"Miami Gardens\",\"FRA\",\"ENG\",4,6,0,0,2.88,2.88),\n",
    "  (\"East Rutherford\",\"ESP\",\"ARG\",1,0,0,0,0.52,0.09)\n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "15aec21a-795c-4e6a-8d82-bcf549fc5925",
   "metadata": {},
   "source": [
    "- List of teams that played FIFA 2026"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "178d9244-2567-4855-b1c2-ab26f3c70bf5",
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_teams(l):\n",
    "    teamdict = {}\n",
    "    for m in l:\n",
    "        team1,team2 = m[1],m[2]\n",
    "        teamdict[team1] = 1\n",
    "        teamdict[team2] = 2\n",
    "    return(sorted(list(teamdict)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "c2881bd6-f0aa-4220-b8d2-2d17f4e1a299",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['ALG',\n",
       " 'ARG',\n",
       " 'AUS',\n",
       " 'AUT',\n",
       " 'BEL',\n",
       " 'BIH',\n",
       " 'BRA',\n",
       " 'CAN',\n",
       " 'CIV',\n",
       " 'COD',\n",
       " 'COL',\n",
       " 'CPV',\n",
       " 'CRO',\n",
       " 'CUW',\n",
       " 'CZE',\n",
       " 'ECU',\n",
       " 'EGY',\n",
       " 'ENG',\n",
       " 'ESP',\n",
       " 'FRA',\n",
       " 'GER',\n",
       " 'GHA',\n",
       " 'HAI',\n",
       " 'IRN',\n",
       " 'IRQ',\n",
       " 'JOR',\n",
       " 'JPN',\n",
       " 'KOR',\n",
       " 'KSA',\n",
       " 'MAR',\n",
       " 'MEX',\n",
       " 'NED',\n",
       " 'NOR',\n",
       " 'NZL',\n",
       " 'PAN',\n",
       " 'PAR',\n",
       " 'POR',\n",
       " 'QAT',\n",
       " 'RSA',\n",
       " 'SCO',\n",
       " 'SEN',\n",
       " 'SUI',\n",
       " 'SWE',\n",
       " 'TUN',\n",
       " 'TUR',\n",
       " 'URU',\n",
       " 'USA',\n",
       " 'UZB']"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_teams(matchlist)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9fc0e730-c0db-433c-92a6-f069b20109d9",
   "metadata": {},
   "source": [
    "- We would like this list in terms of full country names rather than 3 letter abbreviations\n",
    "- Replace each abbreviation by the corresponding country name"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2e82f948-c993-4a3b-a292-e67f42fd4809",
   "metadata": {},
   "source": [
    "### Map\n",
    "- Apply a function $f()$ to each element in a list\n",
    "- Convert $[x_0,x_1,\\ldots,x_{n-1}]$ to $[f(x_0),f(x_1),\\ldots,f(x_{n-1})]$\n",
    "- In Python, `map(f,l)` applies `f` to each element of `l`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d5bf4f17-5a4c-4b0f-b238-15b51396d1a5",
   "metadata": {},
   "source": [
    "**Example**\n",
    "- List full names of teams that played in FIFA 2026\n",
    "- First, a function to map team abbreviations to full names, using a dictionary"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "e3c85b87-4a79-447b-9c1d-7309d5029bb7",
   "metadata": {},
   "outputs": [],
   "source": [
    "def expand(s):\n",
    "    teamdict = {\n",
    "        'ALG':'Algeria',\n",
    "        'ARG':'Argentina',\n",
    "        'AUS':'Australia',\n",
    "        'AUT':'Austria',\n",
    "        'BEL':'Belgium',\n",
    "        'BIH':'Bosnia Herzegovina',\n",
    "        'BRA':'Brazil',\n",
    "        'CAN':'Canada',\n",
    "        'CIV':'Ivory Coast',\n",
    "        'COD':'Congo',\n",
    "        'COL':'Colombia',\n",
    "        'CPV':'Cape Verde',\n",
    "        'CRO':'Croatia',\n",
    "        'CUW':'Curacao',\n",
    "        'CZE':'Czech Republic',\n",
    "        'ECU':'Ecuador',\n",
    "        'EGY':'Egypt',\n",
    "        'ENG':'England',\n",
    "        'ESP':'Spain',\n",
    "        'FRA':'France',\n",
    "        'GER':'Germany',\n",
    "        'GHA':'Ghana',\n",
    "        'HAI':'Haiti',\n",
    "        'IRN':'Iran',\n",
    "        'IRQ':'Iraq',\n",
    "        'JOR':'Jordan',\n",
    "        'JPN':'Japan',\n",
    "        'KOR':'Korea',\n",
    "        'KSA':'Saudi Arabia',\n",
    "        'MAR':'Morocco',\n",
    "        'MEX':'Mexico',\n",
    "        'NED':'Netherlands',\n",
    "        'NOR':'Norway',\n",
    "        'NZL':'New Zealand',\n",
    "        'PAN':'Panama',\n",
    "        'PAR':'Paraguay',\n",
    "        'POR':'Portugal',\n",
    "        'QAT':'Qatar',\n",
    "        'RSA':'South Africa',\n",
    "        'SCO':'Scotland',\n",
    "        'SEN':'Senegal',\n",
    "        'SUI':'Switzerland',\n",
    "        'SWE':'Sweden',\n",
    "        'TUN':'Tunisia',\n",
    "        'TUR':'Turkey',\n",
    "        'URU':'Uruguay',\n",
    "        'USA':'United States of America',\n",
    "        'UZB':'Uzbekistan'}\n",
    "    if (s in teamdict):\n",
    "        return(teamdict[s])\n",
    "    else:\n",
    "        return('No info')\n",
    "    \n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d431b780-8661-4154-93ae-6726818c800c",
   "metadata": {},
   "source": [
    "- Now, we can `map` this function to the outcome of our earlier function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "433010eb-0e51-4f90-ab60-8bbd3db74292",
   "metadata": {},
   "outputs": [],
   "source": [
    "teams = get_teams(matchlist)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "4d4aef75-a130-4fff-b98e-7b32111ccbf9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['ALG',\n",
       " 'ARG',\n",
       " 'AUS',\n",
       " 'AUT',\n",
       " 'BEL',\n",
       " 'BIH',\n",
       " 'BRA',\n",
       " 'CAN',\n",
       " 'CIV',\n",
       " 'COD',\n",
       " 'COL',\n",
       " 'CPV',\n",
       " 'CRO',\n",
       " 'CUW',\n",
       " 'CZE',\n",
       " 'ECU',\n",
       " 'EGY',\n",
       " 'ENG',\n",
       " 'ESP',\n",
       " 'FRA',\n",
       " 'GER',\n",
       " 'GHA',\n",
       " 'HAI',\n",
       " 'IRN',\n",
       " 'IRQ',\n",
       " 'JOR',\n",
       " 'JPN',\n",
       " 'KOR',\n",
       " 'KSA',\n",
       " 'MAR',\n",
       " 'MEX',\n",
       " 'NED',\n",
       " 'NOR',\n",
       " 'NZL',\n",
       " 'PAN',\n",
       " 'PAR',\n",
       " 'POR',\n",
       " 'QAT',\n",
       " 'RSA',\n",
       " 'SCO',\n",
       " 'SEN',\n",
       " 'SUI',\n",
       " 'SWE',\n",
       " 'TUN',\n",
       " 'TUR',\n",
       " 'URU',\n",
       " 'USA',\n",
       " 'UZB']"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "teams"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bc7ea479-a50b-4917-874d-5e2dd3fac3b9",
   "metadata": {},
   "source": [
    "- Output of `map` is a sequence, but not a list, like `range`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "6869bb8d-a568-42c1-82b7-9f47c14d20cb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<map at 0x7f55b42846a0>"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "map(expand,teams)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b0bb5bb5-3c14-48ee-88c7-3907d19e5a96",
   "metadata": {},
   "source": [
    "- Explicitly convert it to a list to view the output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "b13d6001-7687-4ec5-a2ca-23d518449fac",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Algeria',\n",
       " 'Argentina',\n",
       " 'Australia',\n",
       " 'Austria',\n",
       " 'Belgium',\n",
       " 'Bosnia Herzegovina',\n",
       " 'Brazil',\n",
       " 'Canada',\n",
       " 'Ivory Coast',\n",
       " 'Congo',\n",
       " 'Colombia',\n",
       " 'Cape Verde',\n",
       " 'Croatia',\n",
       " 'Curacao',\n",
       " 'Czech Republic',\n",
       " 'Ecuador',\n",
       " 'Egypt',\n",
       " 'England',\n",
       " 'Spain',\n",
       " 'France',\n",
       " 'Germany',\n",
       " 'Ghana',\n",
       " 'Haiti',\n",
       " 'Iran',\n",
       " 'Iraq',\n",
       " 'Jordan',\n",
       " 'Japan',\n",
       " 'Korea',\n",
       " 'Saudi Arabia',\n",
       " 'Morocco',\n",
       " 'Mexico',\n",
       " 'Netherlands',\n",
       " 'Norway',\n",
       " 'New Zealand',\n",
       " 'Panama',\n",
       " 'Paraguay',\n",
       " 'Portugal',\n",
       " 'Qatar',\n",
       " 'South Africa',\n",
       " 'Scotland',\n",
       " 'Senegal',\n",
       " 'Switzerland',\n",
       " 'Sweden',\n",
       " 'Tunisia',\n",
       " 'Turkey',\n",
       " 'Uruguay',\n",
       " 'United States of America',\n",
       " 'Uzbekistan']"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(map(expand,teams))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8ef3bdf5-ddb5-4f28-bf31-2c9378f98bb6",
   "metadata": {},
   "source": [
    "- Since `expand` returns `No info` for unknown keys, the following works\n",
    "- Note that keys need not be of uniform type: `7` is merely an unknown key, not an invalid one because it is not a string"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "521b8fa7-f11d-4a1a-9ab9-47cbb6f8b7bf",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['No info', 'No info', 'No info']"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(map(expand,['xxx','yyy',7]))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85a54f32-31af-4cce-af8f-05e437a88ea3",
   "metadata": {},
   "source": [
    "- `map(f,l)` is a shortcut for the following iteration\n",
    "```\n",
    "outputlist = []\n",
    "for x in l:\n",
    "   outputlist.append(f(x))\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "f0cd1f3f-9613-4259-9f31-d77381e3ae2f",
   "metadata": {},
   "outputs": [],
   "source": [
    "expandedlist = []\n",
    "for t in teams:\n",
    "    expandedlist.append(expand(t))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "be137508-da44-4795-b582-b9cdc2174d43",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Algeria',\n",
       " 'Argentina',\n",
       " 'Australia',\n",
       " 'Austria',\n",
       " 'Belgium',\n",
       " 'Bosnia Herzegovina',\n",
       " 'Brazil',\n",
       " 'Canada',\n",
       " 'Ivory Coast',\n",
       " 'Congo',\n",
       " 'Colombia',\n",
       " 'Cape Verde',\n",
       " 'Croatia',\n",
       " 'Curacao',\n",
       " 'Czech Republic',\n",
       " 'Ecuador',\n",
       " 'Egypt',\n",
       " 'England',\n",
       " 'Spain',\n",
       " 'France',\n",
       " 'Germany',\n",
       " 'Ghana',\n",
       " 'Haiti',\n",
       " 'Iran',\n",
       " 'Iraq',\n",
       " 'Jordan',\n",
       " 'Japan',\n",
       " 'Korea',\n",
       " 'Saudi Arabia',\n",
       " 'Morocco',\n",
       " 'Mexico',\n",
       " 'Netherlands',\n",
       " 'Norway',\n",
       " 'New Zealand',\n",
       " 'Panama',\n",
       " 'Paraguay',\n",
       " 'Portugal',\n",
       " 'Qatar',\n",
       " 'South Africa',\n",
       " 'Scotland',\n",
       " 'Senegal',\n",
       " 'Switzerland',\n",
       " 'Sweden',\n",
       " 'Tunisia',\n",
       " 'Turkey',\n",
       " 'Uruguay',\n",
       " 'United States of America',\n",
       " 'Uzbekistan']"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "expandedlist"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8a878ee4-04c5-4437-bc3c-335c63a83eba",
   "metadata": {},
   "source": [
    "### Filter\n",
    "- Extract items from a list that satisfy a property\n",
    "    - For instance, extract the even numbers from a list of numbers\n",
    "- A *property* is a function $p()$ that maps each input to `True` or `False\n",
    "    - Check if each item $x$ in a list satisfies a property $p(x)$\n",
    "    - Retain only such elements\n",
    "    - Filters out elements that do not satisfy $p()$\n",
    "- In Python, `filter(p,l)`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1ac198ce-9306-4816-83cd-783cc6bd17ed",
   "metadata": {},
   "source": [
    "**Example**\n",
    "- List matches where MEX was the home team\n",
    "- First define the filter function -- returns `True` or `False`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "b4596803-4112-4f31-a66d-3c0f24d62d59",
   "metadata": {},
   "outputs": [],
   "source": [
    "def myfilter(m):            # Take one match tuple as input\n",
    "    return (m[1] == 'MEX')  # Check if the home team in this match is MEX"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5e3814e6-078c-4153-9ec8-eb692d224cfb",
   "metadata": {},
   "source": [
    "- Now, filter matchlist using this function\n",
    "- As with `map`, the output is a sequence, but not a list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "id": "0de1103f-4f8f-4220-b6ae-f788f4e6f426",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<filter at 0x7f55b4286e30>"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "filter(myfilter,matchlist)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "77f65963",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[('Mexico City', 'MEX', 'RSA', 2, 0, 0, 0, 1.84, 0.52),\n",
       " ('Atlanta', 'MEX', 'KOR', 1, 0, 0, 0, 1.62, 0.58),\n",
       " ('Mexico City', 'MEX', 'ECU', 2, 0, 0, 0, 1.02, 0.73),\n",
       " ('Mexico City', 'MEX', 'ENG', 2, 3, 0, 0, 1.88, 1.61)]"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(filter(myfilter,matchlist))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "647c9791-943e-44c1-986b-7bdb8d8781cb",
   "metadata": {},
   "source": [
    "- Note that `filter` does not modify any values in the list\n",
    "- It only copies those elements that satisfy the given property"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a712f7e7-11c0-406d-8d02-8c79d3ffbaed",
   "metadata": {},
   "source": [
    "- Like `map`, `filter(p,l)` is equivalent to an iteration\n",
    "```\n",
    "outputlist = []\n",
    "for x in l:\n",
    "    if p(x):\n",
    "        l.append(x)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "id": "ff31532e-6d86-4336-bb71-c6e0365acc9d",
   "metadata": {},
   "outputs": [],
   "source": [
    "filteredlist = []\n",
    "for m in matchlist:\n",
    "    if myfilter(m):\n",
    "        filteredlist.append(m)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "id": "eb3ecf07-0d63-4869-90a5-03b46d6ec761",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[('Mexico City', 'MEX', 'RSA', 2, 0, 0, 0, 1.84, 0.52),\n",
       " ('Atlanta', 'MEX', 'KOR', 1, 0, 0, 0, 1.62, 0.58),\n",
       " ('Mexico City', 'MEX', 'ECU', 2, 0, 0, 0, 1.02, 0.73),\n",
       " ('Mexico City', 'MEX', 'ENG', 2, 3, 0, 0, 1.88, 1.61)]"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "filteredlist"
   ]
  }
 ],
 "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
}
