{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Collections\n",
    "\n",
    "**Prerequisites**\n",
    "\n",
    "- [Core data types](https://datascience.quantecon.org/basics.html)  \n",
    "\n",
    "\n",
    "**Outcomes**\n",
    "\n",
    "- Ordered Collections  \n",
    "  \n",
    "  - Know what a list is and a tuple is  \n",
    "  - Know how to tell a list from a tuple  \n",
    "  - Understand the `range`, `zip` and `enumerate` functions  \n",
    "  - Be able to use common list methods like `append`, `sort`,\n",
    "    and `reverse`  \n",
    "  \n",
    "- Associative Collections  \n",
    "  \n",
    "  - Understand what a `dict` is  \n",
    "  - Know the distinction between a dicts keys and values  \n",
    "  - Understand when `dict`s are useful  \n",
    "  - Be familiar with common `dict` methods  \n",
    "  \n",
    "- Sets  (optional)  \n",
    "  \n",
    "  - Know what a set is  \n",
    "  - Understand how a set differs from a list and a tuple  \n",
    "  - Know when to use a set vs a list or a tuple  \n",
    "  \n",
    "\n",
    "\n",
    "**Outline**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Contents\n",
    "\n",
    "- [Collections](#Collections)  \n",
    "  - [Ordered Collections](#Ordered-Collections)  \n",
    "  - [Associative Collections](#Associative-Collections)  \n",
    "  - [Exercises](#Exercises)  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Ordered Collections"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Lists\n",
    "\n",
    "A Python list is an ordered collection of items.\n",
    "\n",
    "We can create lists using the following syntax"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hide-output": false
   },
   "source": [
    "```python\n",
    "[item1, item2, ...,  itemN]\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "where the `...` represents any number of additional items.\n",
    "\n",
    "Each item can be of any type.\n",
    "\n",
    "Let’s create some lists."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[2.0, 9.1, 12.5]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# created, but not assigned to a variable\n",
    "[2.0, 9.1, 12.5]\n",
    "#keep the data in one place since the individual is an object "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x has type <class 'list'>\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[2.0, 9.1, 12.5]"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# stored as the variable `x`\n",
    "#seperate by comma \n",
    "x = [2.0, 9.1, 12.5]\n",
    "print(\"x has type\", type(x)) #x in this is a list \n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "this is the case of x which is equal to [2.0, 9.1, 12.5]\n"
     ]
    }
   ],
   "source": [
    "print(f\"this is the case of x which is equal to {x}\") #function = f"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(x) #review the element how many object they have"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.0"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[0] # to review the first element "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "x.append(10) #mean you want to add more in the list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[2.0, 9.1, 12.5, 10, 12]"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "x.extend([10,12])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[2.0, 9.1, 12.5, 10, 12]"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### What Can We Do with Lists?\n",
    "\n",
    "We can access items in a list called `mylist` using `mylist[N]`\n",
    "where `N` is an integer.\n",
    "\n",
    "Note: Anytime that we use the syntax `x[i]` we are doing what is\n",
    "called indexing – it means that we are selecting a particular element\n",
    "of a *collection* `x`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "9.1"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Wait? Why did `x[1]` return `9.1` when the first element in x is\n",
    "actually `2.0`?\n",
    "\n",
    "This happened because Python starts counting at zero!\n",
    "\n",
    "Lets repeat that one more time for emphasis **Python starts counting at zero**!\n",
    "\n",
    "To access the first element of x we must use `x[0]`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.0"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also determine how many items are in a list using the `len` function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What happens if we try to index with a number higher than the number of\n",
    "items in a list?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "# uncomment the line below and run\n",
    "# x[4]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can check if a list contains an element using the `in` keyword."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2.0 in x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1.5 in x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For our list `x`, other common operations we might want to do are…"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[12, 10, 12.5, 9.1, 2.0]"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.reverse() #reverse the list \n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[10, 25, 42, 1.0]\n",
      "[1.0, 10, 25, 42]\n"
     ]
    }
   ],
   "source": [
    "number_list = [10, 25, 42, 1.0]\n",
    "print(number_list)\n",
    "number_list.sort()\n",
    "print(number_list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "number_list = [10, 25, 42, 1.0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[10, 25, 42, 1.0]\n"
     ]
    }
   ],
   "source": [
    "print(number_list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "number_list.extend([12,11])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[10, 25, 42, 1.0, 12, 11]\n"
     ]
    }
   ],
   "source": [
    "print(number_list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "number_list.sort()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1.0, 10, 11, 12, 25, 42]\n"
     ]
    }
   ],
   "source": [
    "print(number_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that in order to `sort`, we had to have all elements in our list\n",
    "be numbers (`int` and `float`), more on this [below](#inhomogenous-lists).\n",
    "\n",
    "We could actually do the same with a list of strings. In this case, `sort`\n",
    "will put the items in alphabetical order."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['NY', 'AZ', 'TX']\n",
      "['AZ', 'NY', 'TX']\n"
     ]
    }
   ],
   "source": [
    "str_list = [\"NY\", \"AZ\", \"TX\"]\n",
    "print(str_list)\n",
    "str_list.sort()\n",
    "print(str_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `append` method adds an element to the end of existing list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "num_list = [10, 25, 42, 8]\n",
    "print(num_list)\n",
    "num_list.append(10)\n",
    "print(num_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "However, if you call `append` with a list, it adds a `list` to the end,\n",
    "rather than the numbers in that list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "num_list = [10, 25, 42, 8]\n",
    "print(num_list)\n",
    "num_list.append([20, 4])\n",
    "print(num_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To combine the lists instead…"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "num_list = [10, 25, 42, 8]\n",
    "print(num_list)\n",
    "num_list.extend([20, 4])\n",
    "print(num_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<a id='exercise-0'></a>\n",
    "> See exercise 1 in the [*exercise list*](https://datascience.quantecon.org/#exerciselist-0)\n",
    "\n",
    "\n",
    "\n",
    "<a id='inhomogenous-lists'></a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Lists of Different Types\n",
    "\n",
    "While most examples above have all used a `list` with\n",
    "a single type of variable, this is not required.\n",
    "\n",
    "Let’s carefully make a small change to the first example: replace `2.0` with `2`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "x = [2, 9.1, 12.5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x has the value [2, 9.1, 12.5]\n"
     ]
    }
   ],
   "source": [
    "print(f\"x has the value {x}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This behavior is identical for many operations you might\n",
    "apply to a list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "x = [2, 9.1, 12.5, 13.4, 124]\n",
    "np.mean(x) == sum(x)/len(x) #== represent the logical ideal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "32.2"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.mean(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "32.2"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sum(x)/len(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "12.5"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.median(x) #for checking the data might be wrong "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here we have also introduced a new [module](https://datascience.quantecon.org/basics.html#modules),\n",
    "[Numpy](https://datascience.quantecon.org/../scientific/index.html), which provides many functions\n",
    "for working with numeric data.\n",
    "\n",
    "Taking this further, we can put completely different types of elements\n",
    "inside of a list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x has type <class 'list'>\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[2, 'hello', 3.0]"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# stored as the variable `x`\n",
    "x = [2, \"hello\", 3.0]\n",
    "print(\"x has type\", type(x))\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To see the types of individual elements in the list:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "type(x[0]) = <class 'int'>, type(x[1]) = <class 'float'>, type(x[2]) = <class 'float'>\n"
     ]
    }
   ],
   "source": [
    "print(f\"type(x[0]) = {type(x[0])}, type(x[1]) = {type(x[1])}, type(x[2]) = {type(x[2])}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "While no programming limitations prevent this, you should be careful if you write code\n",
    "with different numeric and non-numeric types in the same list.\n",
    "\n",
    "For example, if the types within the list cannot be compared, then how could you sort the elements of the list? (i.e. How do you determine whether the string “hello” is less than the integer 2, “hello” < 2?)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "x = [2, \"hello\", 3.0]\n",
    "# uncomment the line below and see what happens!\n",
    "# x.sort()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'<' not supported between instances of 'str' and 'int'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "Input \u001b[0;32mIn [27]\u001b[0m, in \u001b[0;36m<cell line: 1>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mx\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msort\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[0;31mTypeError\u001b[0m: '<' not supported between instances of 'str' and 'int'"
     ]
    }
   ],
   "source": [
    "x.sort()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A few key exceptions to this general rule are:\n",
    "\n",
    "- Lists with both integers and floating points are less error-prone\n",
    "  (since mathematical code using the list would work with both types).  \n",
    "- When working with lists and data, you may want to represent missing\n",
    "  values with a different type than the existing values.  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The `range` Function\n",
    "\n",
    "One function you will see often in Python is the `range` function.\n",
    "\n",
    "It has three versions:\n",
    "\n",
    "1. `range(N)`: goes from 0 to N-1  \n",
    "1. `range(a, N)`: goes from a to N-1  \n",
    "1. `range(a, N, d)`: goes from a to N-1, counting by d  \n",
    "\n",
    "\n",
    "When we call the `range` function, we get back something that has type `range`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "type(r) <class 'range'>\n"
     ]
    }
   ],
   "source": [
    "r = range(5) # to create the range of the data, assign the index range  \n",
    "print(\"type(r)\", type(r))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 2, 3, 4]"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(r) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "range(2000, 2036, 2)"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "range(2000,2036,2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "range(2000, 2010)"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "range(2000,2010)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009]"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(range(2000,2010))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[2000,\n",
       " 2002,\n",
       " 2004,\n",
       " 2006,\n",
       " 2008,\n",
       " 2010,\n",
       " 2012,\n",
       " 2014,\n",
       " 2016,\n",
       " 2018,\n",
       " 2020,\n",
       " 2022,\n",
       " 2024,\n",
       " 2026,\n",
       " 2028,\n",
       " 2030,\n",
       " 2032,\n",
       " 2034,\n",
       " 2036]"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(range(2000,2037,2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[2, 9.1, 12.5, 13.4, 124]"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(x) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "range(0, 5)"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "range(len(x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 2, 3, 4]"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(range(len(x)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To turn the `range` into a list:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 2, 3, 4]"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(r)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<a id='exercise-1'></a>\n",
    "> See exercise 2 in the [*exercise list*](https://datascience.quantecon.org/#exerciselist-0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### What are Tuples?\n",
    "\n",
    "Tuples are very similar to lists and hold ordered collections of items.\n",
    "\n",
    "However, tuples and lists have three main differences:\n",
    "\n",
    "1. Tuples are created using parenthesis — `(` and `)` — instead of\n",
    "  square brackets — `[` and `]`.  \n",
    "1. Tuples are *immutable*, which is a fancy computer science word\n",
    "  meaning that they can’t be changed or altered after they are created.  \n",
    "1. Tuples and multiple return values\n",
    "  from functions are tightly connected, as we will see in [functions](https://datascience.quantecon.org/functions.html).  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "t is a <class 'tuple'>\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(1, 'hello', 3.0)"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t = (1, \"hello\", 3.0)  #you want to fix the order of the data \n",
    "print(\"t is a\", type(t))\n",
    "t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'hello'"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t[1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can *convert* a list to a tuple by calling the `tuple` function on\n",
    "a list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x is a <class 'list'>\n",
      "tuple(x) is a <class 'tuple'>\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(2, 9.1, 12.5, 13.4, 124)"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(\"x is a\", type(x))\n",
    "print(\"tuple(x) is a\", type(tuple(x)))\n",
    "tuple(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also convert a tuple to a list using the list function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "list(t)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As with a list, we access items in a tuple `t` using `t[N]` where\n",
    "`N` is an int."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "t[0]  # still start counting at 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "t[2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<a id='exercise-2'></a>\n",
    "> See exercise 3 in the [*exercise list*](https://datascience.quantecon.org/#exerciselist-0)\n",
    "\n",
    "\n",
    "Tuples (and lists) can be unpacked directly into variables."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [],
   "source": [
    "x =[[\"cat\",\"fish\"],\"dog\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "a,b = x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['cat', 'fish']"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = 1, y = test\n"
     ]
    }
   ],
   "source": [
    "x, y = (1, \"test\")\n",
    "print(f\"x = {x}, y = {y}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This will be a convenient way to work with functions returning\n",
    "multiple values, as well as within [comprehensions and loops](https://datascience.quantecon.org/control_flow.html)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### List vs Tuple: Which to Use?\n",
    "\n",
    "Should you use a list or tuple?\n",
    "\n",
    "This depends on what you are storing, whether you might need to reorder the elements,\n",
    "or whether you’d add\n",
    "new elements without a complete reinterpretation of the\n",
    "underlying data.\n",
    "\n",
    "For example, take data representing the GDP (in trillions) and population\n",
    "(in billions) for China in 2015."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('China', 2015, 11.06, 1.371)\n"
     ]
    }
   ],
   "source": [
    "china_data_2015 = (\"China\", 2015, 11.06, 1.371)\n",
    "\n",
    "print(china_data_2015)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this case, we have used a tuple since: (a) ordering would\n",
    "be meaningless; and (b) adding more data would require a\n",
    "reinterpretation of the whole data structure.\n",
    "\n",
    "On the other hand, consider a list of GDP in China between\n",
    "2013 and 2015."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[9.607, 10.48, 11.06]\n"
     ]
    }
   ],
   "source": [
    "gdp_data = [9.607, 10.48, 11.06]\n",
    "print(gdp_data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this case, we have used a list, since adding on a new\n",
    "element to the end of the list for GDP in 2016 would make\n",
    "complete sense.\n",
    "\n",
    "Along these lines, collecting data on China for different\n",
    "years may make sense as a list of tuples (e.g. year, GDP,\n",
    "and population – although we will see better ways to store this sort of data\n",
    "in the [Pandas](https://datascience.quantecon.org/../pandas/index.html) section)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(2015, 11.06, 1.371), (2014, 10.48, 1.364), (2013, 9.607, 1.357)]\n"
     ]
    }
   ],
   "source": [
    "china_data = [(2015, 11.06, 1.371), (2014, 10.48, 1.364), (2013, 9.607, 1.357)]\n",
    "print(china_data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [],
   "source": [
    "population=[china_data[0][2],china_data[1][2],china_data[2][2]] # the first on is the list of the first and the second order"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1.371, 1.364, 1.357]"
      ]
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "population"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In general, a rule of thumb is to use a list unless you *need* to use a tuple.\n",
    "\n",
    "Key criteria for tuple use are when you want to:\n",
    "\n",
    "- ensure the *order* of elements can’t change  \n",
    "- ensure the actual values of the elements can’t\n",
    "  change  \n",
    "- use the collection as a key in a dict (we will learn what this\n",
    "  means [soon](https://datascience.quantecon.org/.html))  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `zip` and `enumerate`\n",
    "\n",
    "Two functions that can be extremely useful are `zip` and `enumerate`.\n",
    "\n",
    "Both of these functions are best understood by example, so let’s see\n",
    "them in action and then talk about what they do."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "type(z) <class 'zip'>\n"
     ]
    }
   ],
   "source": [
    "gdp_data = [9.607, 10.48, 11.06]\n",
    "years = [2013, 2014, 2015]\n",
    "z = zip(years, gdp_data)\n",
    "print(\"type(z)\", type(z))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To see what is inside `z`, let’s convert it to a list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<zip at 0x7ff6af142a80>"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "z"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(2013, 9.607), (2014, 10.48), (2015, 11.06)]"
      ]
     },
     "execution_count": 99,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice that we now have a list where each item is a tuple.\n",
    "\n",
    "Within each tuple, we have one item from each of the collections we\n",
    "passed to the zip function.\n",
    "\n",
    "In particular, the first item in `z` contains the first item from\n",
    "`[2013, 2014, 2015]` and the first item from `[9.607, 10.48, 11.06]`.\n",
    "\n",
    "The second item in `z` contains the second item from each collection\n",
    "and so on.\n",
    "\n",
    "We can access an element in this and then unpack the resulting\n",
    "tuple directly into variables."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "year = 2013, GDP = 9.607\n",
      "year = 2014, GDP = 10.48\n",
      "year = 2015, GDP = 11.06\n"
     ]
    }
   ],
   "source": [
    "l = list(zip(years, gdp_data))\n",
    "x, y = l[0]\n",
    "print(f\"year = {x}, GDP = {y}\")\n",
    "x, y = l[1]\n",
    "print(f\"year = {x}, GDP = {y}\")\n",
    "x, y = l[2]\n",
    "print(f\"year = {x}, GDP = {y}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let’s experiment with `enumerate`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "type(e) <class 'enumerate'>\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<enumerate at 0x7fa73e44b5c0>"
      ]
     },
     "execution_count": 102,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "e = enumerate([\"a\", \"b\", \"c\"]) \n",
    "print(\"type(e)\", type(e))\n",
    "e"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Again, we call `list(e)` to see what is inside."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(0, 'a'), (1, 'b'), (2, 'c')]"
      ]
     },
     "execution_count": 103,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(e)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We again have a list of tuples, but this time, the first element in each\n",
    "tuple is the *index* of the second tuple element in the initial\n",
    "collection.\n",
    "\n",
    "Notice that the third item is `(2, 'c')` because\n",
    "`[\"a\", \"b\", \"c\"][2]` is `'c'`\n",
    "\n",
    "\n",
    "<a id='exercise-3'></a>\n",
    "> See exercise 4 in the [*exercise list*](https://datascience.quantecon.org/#exerciselist-0)\n",
    "\n",
    "\n",
    "An important quirk of some iterable types that are not lists (such as the above `zip`) is that\n",
    "you cannot convert the same type to a list twice.\n",
    "\n",
    "This is because `zip`, `enumerate`, and `range` produce what is called a generator.\n",
    "\n",
    "A generator will only produce each of its elements a single time, so if you call `list` on the same\n",
    "generator a second time, it will not have any elements to iterate over anymore.\n",
    "\n",
    "For more information, refer to the [Python documentation](https://docs.python.org/3/howto/functional.html#generators)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(2013, 9.607), (2014, 10.48), (2015, 11.06)]\n",
      "[]\n"
     ]
    }
   ],
   "source": [
    "gdp_data = [9.607, 10.48, 11.06]\n",
    "years = [2013, 2014, 2015]\n",
    "z = zip(years, gdp_data)\n",
    "l = list(z)\n",
    "print(l)\n",
    "m = list(z)\n",
    "print(m)  #if use the comman list you get the solution the second time will create the empty list "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Associative Collections"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Dictionaries\n",
    "\n",
    "A dictionary (or dict) associates `key`s with `value`s.\n",
    "\n",
    "It will feel similar to a dictionary for words, where the keys are words and\n",
    "the values are the associated definitions.\n",
    "\n",
    "The most common way to create a `dict` is to use curly braces — `{`\n",
    "and `}` — like this:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hide-output": false
   },
   "source": [
    "```python\n",
    "{\"key1\": value1, \"key2\": value2, ..., \"keyN\": valueN}\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "where the `...` indicates that we can have any number of additional\n",
    "terms.\n",
    "\n",
    "The crucial part of the syntax is that each key-value pair is written\n",
    "`key: value` and that these pairs are separated by commas — `,`.\n",
    "\n",
    "Let’s see an example using our aggregate data on China in 2015."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {
    "hide-output": false,
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'country': 'China', 'year': 2015, 'GDP': 11.06, 'population': 1.371}\n"
     ]
    }
   ],
   "source": [
    "china_data = {\"country\": \"China\", \"year\": 2015, \"GDP\" : 11.06, \"population\": 1.371}\n",
    "print(china_data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2015"
      ]
     },
     "execution_count": 110,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "china_data[\"year\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {},
   "outputs": [],
   "source": [
    "y = [1,2,3 \\\n",
    "    ]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Unlike our above example using a `tuple`, a `dict` allows us to\n",
    "associate a name with each field, rather than having to remember the\n",
    "order within the tuple.\n",
    "\n",
    "Often, code that makes a dict is easier to read if we put each\n",
    "`key: value` pair on its own line. (Recall our earlier comment on\n",
    "using whitespace effectively to improve readability!)\n",
    "\n",
    "The code below is equivalent to what we saw above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "china_data = {\n",
    "    \"country\": \"China\",\n",
    "    \"year\": 2015,\n",
    "    \"GDP\" : 11.06,\n",
    "    \"population\": 1.371\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Most often, the keys (e.g. “country”, “year”, “GDP”, and “population”)\n",
    "will be strings, but we could also use numbers (`int`, or\n",
    "`float`) or even tuples (or, rarely, a combination of types).\n",
    "\n",
    "The values can be **any** type and different from each other.\n",
    "\n",
    "\n",
    "<a id='exercise-4'></a>\n",
    "> See exercise 5 in the [*exercise list*](https://datascience.quantecon.org/#exerciselist-0)\n",
    "\n",
    "\n",
    "This next example is meant to emphasize how values can be\n",
    "*anything* – including another dictionary."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'AAPL': {'bid': 175.96, 'ask': 175.98}, 'GE': {'bid': 1047.03, 'ask': 1048.4}, 'TVIX': {'bid': 8.38, 'ask': 8.4}}\n"
     ]
    }
   ],
   "source": [
    "companies = {\"AAPL\": {\"bid\": 175.96, \"ask\": 175.98},\n",
    "             \"GE\": {\"bid\": 1047.03, \"ask\": 1048.40},\n",
    "             \"TVIX\": {\"bid\": 8.38, \"ask\": 8.40}}\n",
    "print(companies)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "175.96"
      ]
     },
     "execution_count": 115,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "companies[\"AAPL\"][\"bid\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Getting, Setting, and Updating dict Items\n",
    "\n",
    "We can now ask Python to tell us the value for a particular key by using\n",
    "the syntax `d[k]`,  where `d` is our `dict` and `k` is the key for which we want to\n",
    "find the value.\n",
    "\n",
    "For example,"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2015\n",
      "country = China, population = 1.371\n"
     ]
    }
   ],
   "source": [
    "print(china_data[\"year\"])\n",
    "print(f\"country = {china_data['country']}, population = {china_data['population']}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note: when inside of a formatting string, you can use `'` instead of `\"` as above\n",
    "to ensure the formatting still works with the embedded code.\n",
    "\n",
    "If we ask for the value of a key that is not in the dict, we will get an error."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "# uncomment the line below to see the error\n",
    "# china_data[\"inflation\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also add new items to a dict using the syntax `d[new_key] = new_value`.\n",
    "\n",
    "Let’s see some examples."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'country': 'China', 'year': 2015, 'GDP': 11.06, 'population': 1.371}\n",
      "{'country': 'China', 'year': 2015, 'GDP': 11.06, 'population': 1.371, 'unemployment': '4.05%'}\n"
     ]
    }
   ],
   "source": [
    "print(china_data)\n",
    "china_data[\"unemployment\"] = \"4.05%\"\n",
    "print(china_data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To update the value, we use assignment in the same way (which will\n",
    "create the key and value as required)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'country': 'China', 'year': 2015, 'GDP': 11.06, 'population': 1.371, 'unemployment': '4.05%'}\n",
      "{'country': 'China', 'year': 2015, 'GDP': 11.06, 'population': 1.371, 'unemployment': '4.051%'}\n"
     ]
    }
   ],
   "source": [
    "print(china_data)\n",
    "china_data[\"unemployment\"] = \"4.051%\"\n",
    "print(china_data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Or we could change the type."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'country': 'China', 'year': 2015, 'GDP': 11.06, 'population': 1.371, 'unemployment': 4.051}\n"
     ]
    }
   ],
   "source": [
    "china_data[\"unemployment\"] = 4.051\n",
    "print(china_data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<a id='exercise-5'></a>\n",
    "> See exercise 6 in the [*exercise list*](https://datascience.quantecon.org/#exerciselist-0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Common `dict` Functionality\n",
    "\n",
    "We can do some common things with dicts.\n",
    "\n",
    "We will demonstrate them with examples below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# number of key-value pairs in a dict\n",
    "len(china_data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "# get a list of all the keys\n",
    "name = list(china_data.keys())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2015"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "china_data[name[1]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['China', 2015, 11.06, 1.371, 4.051]"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# get a list of all the values\n",
    "list(china_data.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'country': 'China',\n",
       " 'year': 2015,\n",
       " 'GDP': 11.06,\n",
       " 'population': 1.371,\n",
       " 'unemployment': 4.051,\n",
       " 'irrigated_land': 690070,\n",
       " 'top_religions': {'buddhist': 18.2, 'christian': 5.1, 'muslim': 1.8}}"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "more_china_data = {\"irrigated_land\": 690_070, \"top_religions\": {\"buddhist\": 18.2, \"christian\" : 5.1, \"muslim\": 1.8}}\n",
    "\n",
    "# Add all key-value pairs in mydict2 to mydict.\n",
    "# if the key already appears in mydict, overwrite the\n",
    "# value with the value in mydict2\n",
    "china_data.update(more_china_data)\n",
    "china_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "690070"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Get the value associated with a key or return a default value\n",
    "# use this to avoid the NameError we saw above if you have a reasonable\n",
    "# default value\n",
    "china_data.get(\"irrigated_land\", \"Data Not Available\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Data Not Available'"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "china_data.get(\"death_rate\", \"Data Not Available\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<a id='exercise-6'></a>\n",
    "> See exercise 7 in the [*exercise list*](https://datascience.quantecon.org/#exerciselist-0)\n",
    "\n",
    "\n",
    "\n",
    "<a id='exercise-7'></a>\n",
    "> See exercise 8 in the [*exercise list*](https://datascience.quantecon.org/#exerciselist-0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Sets (Optional)\n",
    "\n",
    "Python has an additional way to represent collections of items: sets.\n",
    "\n",
    "Sets come up infrequently, but you should be aware of them.\n",
    "\n",
    "If you are familiar with the mathematical concept of sets, then you will\n",
    "understand the majority of Python sets already.\n",
    "\n",
    "If you don’t know the math behind sets, don’t worry: we’ll cover the\n",
    "basics of Python’s sets here.\n",
    "\n",
    "A set is an *unordered* collection of *unique* elements.\n",
    "\n",
    "The syntax for creating a set uses curly bracket `{` and `}`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hide-output": false
   },
   "source": [
    "```python\n",
    "{item1, item2, ..., itemN}\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here is an example."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "s has type <class 'set'>\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{1, 3.0, 'hello'}"
      ]
     },
     "execution_count": 96,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = {1, \"hello\", 3.0}\n",
    "print(\"s has type\", type(s))\n",
    "s"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<a id='exercise-8'></a>\n",
    "> See exercise 9 in the [*exercise list*](https://datascience.quantecon.org/#exerciselist-0)\n",
    "\n",
    "\n",
    "As with lists and tuples, we can check if something is `in` the set\n",
    "and check the set’s length:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "len(s) = 3\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 97,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(\"len(s) =\", len(s))\n",
    "\"hello\" in s"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Unlike lists and tuples, we can’t extract elements of a set `s` using\n",
    "`s[N]` where `N` is a number."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hide-output": false
   },
   "source": [
    "```python\n",
    "# Uncomment the line below to see what happens\n",
    "# s[1]\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is because sets are not ordered, so the notion of getting the\n",
    "second element (`s[1]`) is not well defined.\n",
    "\n",
    "We add elements to a set `s` using `s.add`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 100, 3.0, 'hello'}"
      ]
     },
     "execution_count": 98,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.add(100)\n",
    "s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {
    "hide-output": false,
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 100, 3.0, 'hello'}"
      ]
     },
     "execution_count": 99,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.add(\"hello\") # nothing happens, why?\n",
    "s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 100, 3.0, 'hello', 'world'}"
      ]
     },
     "execution_count": 102,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.union(s2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also do set operations.\n",
    "\n",
    "Consider the set `s` from above and the set\n",
    "`s2 = {\"hello\", \"world\"}`.\n",
    "\n",
    "- `s.union(s2)`: returns a set with all elements in either `s` or\n",
    "  `s2`  \n",
    "- `s.intersection(s2)`: returns a set with all elements in both `s`\n",
    "  and `s2`  \n",
    "- `s.difference(s2)`: returns a set with all elements in `s` that\n",
    "  aren’t in `s2`  \n",
    "- `s.symmetric_difference(s2)`: returns a set with all elements in\n",
    "  only one of `s` and `s2`  \n",
    "\n",
    "\n",
    "\n",
    "<a id='exercise-9'></a>\n",
    "> See exercise 10 in the [*exercise list*](https://datascience.quantecon.org/#exerciselist-0)\n",
    "\n",
    "\n",
    "As with tuples and lists, a `set` function can convert other\n",
    "collections to sets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "x = [1, 2, 3, 1]\n",
    "set(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "t = (1, 2, 3, 1)\n",
    "set(t)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Likewise, we can convert sets to lists and tuples."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "list(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "tuple(s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Exercises\n",
    "Due date: Aug 16, 2022 before NOON\\\\\n",
    "\n",
    "<a id='exerciselist-0'></a>\n",
    "**Exercise 1**\n",
    "\n",
    "In the first cell, try `y.append(z)`.\n",
    "\n",
    "In the second cell try `y.extend(z)`.\n",
    "\n",
    "Explain the behavior.\n",
    "\n",
    "HINT: When you are trying to explain use `y.append?` and `y.extend?` to\n",
    "see a description of what these methods are supposed to do."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "hide-output": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['a', 'b', 'c', [1, 2, 3]]\n"
     ]
    }
   ],
   "source": [
    "y = [\"a\", \"b\", \"c\"]\n",
    "z = [1, 2, 3]\n",
    "y.append(z)\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "hide-output": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['a', 'b', 'c', 1, 2, 3]\n"
     ]
    }
   ],
   "source": [
    "y = [\"a\", \"b\", \"c\"]\n",
    "z = [1, 2, 3]\n",
    "y.extend(z)\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "([*back to text*](https://datascience.quantecon.org/#exercise-0))\n",
    "\n",
    "**Exercise 2**\n",
    "\n",
    "Experiment with the other two versions of the `range` function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": true
   },
   "outputs": [],
   "source": [
    "# try list(range(a, N)) -- you pick `a` and `N`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4, 5, 6, 7, 8, 9]"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(range(1,10))\n",
    "     "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "hide-output": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 3, 5, 7, 9]"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(range(1,10,2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "([*back to text*](https://datascience.quantecon.org/#exercise-1))\n",
    "\n",
    "**Exercise 3**\n",
    "\n",
    "Verify that tuples are indeed immutable by attempting the following:\n",
    "\n",
    "- Changing the first element of `t` to be `100`  \n",
    "- Appending a new element `\"!!\"` to the end of `t` (remember with a\n",
    "  list `x` we would use `x.append(\"!!\")` to do this  \n",
    "- Sorting `t`  \n",
    "- Reversing `t`  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": true
   },
   "outputs": [],
   "source": [
    "# change first element of t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "t\n",
    "fix_t = list(t)\n",
    "fix_t[0] = 100\n",
    "t = tuple(fix_t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(100, 'hello', 3.0)\n"
     ]
    }
   ],
   "source": [
    "print(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "hide-output": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(100, 'hello', 3.0, '!!')\n"
     ]
    }
   ],
   "source": [
    "ts = list(t)\n",
    "ts.append(\"!!\")\n",
    "t = tuple(ts)\n",
    "print(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "hide-output": true
   },
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'<' not supported between instances of 'float' and 'str'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "Input \u001b[0;32mIn [37]\u001b[0m, in \u001b[0;36m<cell line: 3>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m t\n\u001b[1;32m      2\u001b[0m ts \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mlist\u001b[39m(t)\n\u001b[0;32m----> 3\u001b[0m \u001b[43mts\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msort\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[0;31mTypeError\u001b[0m: '<' not supported between instances of 'float' and 'str'"
     ]
    }
   ],
   "source": [
    "t\n",
    "ts = list(t)\n",
    "ts.sort()\n",
    "#we can not sort the data between float and str "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "hide-output": true,
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['!!', 3.0, 'hello', 100]\n",
      "('!!', 3.0, 'hello', 100)\n"
     ]
    }
   ],
   "source": [
    "t\n",
    "ts = list(t)\n",
    "ts.reverse()\n",
    "print(ts)\n",
    "t = tuple(ts)\n",
    "print(t)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "([*back to text*](https://datascience.quantecon.org/#exercise-2))\n",
    "\n",
    "**Exercise 4**\n",
    "\n",
    "**Challenging** For the tuple `foo` below, use a combination of `zip`,\n",
    "`range`, and `len` to mimic `enumerate(foo)`.\n",
    "\n",
    "Verify that your proposed solution is correct by converting each to a list\n",
    "and checking equality with `==`.\n",
    "\n",
    "HINT: You can see what the answer should look like by starting with\n",
    "`list(enumerate(foo))`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(0, 'good'), (1, 'luck!')]"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(enumerate(foo))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "foo = (\"good\", \"luck!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1]"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(range(len(foo)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "y = zip(list(range(len(foo))),foo)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(0, 'good'), (1, 'luck!')]"
      ]
     },
     "execution_count": 88,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(y) == list(enumerate(foo))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[(0, 'good'), (1, 'luck!')] == [(0, 'good'), (1, 'luck!')]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "([*back to text*](https://datascience.quantecon.org/#exercise-3))\n",
    "\n",
    "**Exercise 5**\n",
    "\n",
    "Create a new dict which associates stock tickers with its stock price.\n",
    "\n",
    "Here are some tickers and a price.\n",
    "\n",
    "- AAPL: 175.96  \n",
    "- GOOGL: 1047.43  \n",
    "- TVIX: 8.38  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'AAPL': {175.96}, 'GOOGL': {1047.43}, 'TVIX': {8.38}}\n"
     ]
    }
   ],
   "source": [
    "trade = {\"AAPL\" : {175.96},\n",
    "      \"GOOGL\" : {1047.43},\n",
    "      \"TVIX\" : {8.38}}\n",
    "print(trade)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "([*back to text*](https://datascience.quantecon.org/#exercise-4))\n",
    "\n",
    "**Exercise 6**\n",
    "\n",
    "Look at the [World Factbook for Australia](https://www.cia.gov/-library/publications/the-world-factbook/geos/as.html)\n",
    "and create a dictionary with data containing the following types:\n",
    "float, string, integer, list, and dict.  Choose any data you wish.\n",
    "\n",
    "To confirm, you should have a dictionary that you identified via a key."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "country ={\"name\" : {\"fiji\"},\n",
    "         \"population\" :{943737},\n",
    "         \"languages\" : {\"English\",\"iTaukei\", \"Fiji Hindi\"},\n",
    "        \"growth_rate\" : {0.44}}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': {'fiji'}, 'population': {943737}, 'languages': {'Fiji Hindi', 'iTaukei', 'English'}, 'growth_rate': {0.44}}\n"
     ]
    }
   ],
   "source": [
    "print(country)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "([*back to text*](https://datascience.quantecon.org/#exercise-5))\n",
    "\n",
    "**Exercise 7**\n",
    "\n",
    "Use Jupyter's help facilities to learn how to use the `pop` method to\n",
    "remove the key `\"irrigated_land\"` (and its value) from the dict."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'country': 'China', 'year': 2015, 'GDP': 11.06, 'population': 1.371, 'unemployment': 4.051, 'irrigated_land': 690070, 'top_religions': {'buddhist': 18.2, 'christian': 5.1, 'muslim': 1.8}}\n",
      "{'country': 'China', 'year': 2015, 'GDP': 11.06, 'population': 1.371, 'unemployment': 4.051, 'top_religions': {'buddhist': 18.2, 'christian': 5.1, 'muslim': 1.8}}\n"
     ]
    }
   ],
   "source": [
    "# uncomment and use the Inspector or ?\n",
    "#china_data.pop(\n",
    "print(china_data)\n",
    "china_data.pop(\"irrigated_land\")\n",
    "print(china_data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "([*back to text*](https://datascience.quantecon.org/#exercise-6))\n",
    "\n",
    "**Exercise 8**\n",
    "\n",
    "Explain what happens to the value you popped.\n",
    "\n",
    "Experiment with calling `pop` twice."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "ename": "KeyError",
     "evalue": "'irrigated_land'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "Input \u001b[0;32mIn [65]\u001b[0m, in \u001b[0;36m<cell line: 1>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mchina_data\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpop\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mirrigated_land\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n",
      "\u001b[0;31mKeyError\u001b[0m: 'irrigated_land'"
     ]
    }
   ],
   "source": [
    "china_data.pop(\"irrigated_land\") # we can not use the pop function as the same key we want to remove since we already remove"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "([*back to text*](https://datascience.quantecon.org/#exercise-7))\n",
    "\n",
    "**Exercise 9**\n",
    "\n",
    "Try creating a set with repeated elements (e.g. `{1, 2, 1, 2, 1, 2}`).\n",
    "\n",
    "What happens?\n",
    "\n",
    "Why?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "s3 = {1, 2, 1, 2, 1, 2}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2}"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s3 # the number are the same and the value will choose only the one that represent"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "([*back to text*](https://datascience.quantecon.org/#exercise-8))\n",
    "\n",
    "**Exercise 10**\n",
    "\n",
    "Test out two of the operations described above using the original set we\n",
    "created, `s`, and the set created below `s2`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "s2 = {\"hello\", \"world\"}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'hello'}"
      ]
     },
     "execution_count": 103,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.intersection(s2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 100, 3.0, 'world'}"
      ]
     },
     "execution_count": 104,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.symmetric_difference(s2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "([*back to text*](https://datascience.quantecon.org/#exercise-9))"
   ]
  }
 ],
 "metadata": {
  "date": 1596739280.9819305,
  "filename": "collections.rst",
  "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.9.12"
  },
  "next_doc": {
   "link": "control_flow",
   "title": "Control Flow"
  },
  "prev_doc": {
   "link": "basics",
   "title": "Basics"
  },
  "title": "Collections"
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
