{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Python Built-in Data Structures"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This section provides a brief overview of \n",
    "\n",
    "* The built-in datastructures in Python -  list, tuples, and dictionaries\n",
    "* For loop"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Lists"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can use lists to store a sequence of values. A list is a collection of references to Python data objects. Note than in Python list indexes start at 0 (similar to C or C++). Different ways of creating lists are shown below"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "a = [] # creates an empty list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "a = [8, 9, 10] # creates a list of three elements\n",
    "b = [10, 7, 18, \"Avi\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "List indices start at 0 from left with positive index. List indices start at -1 from right for negative index."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "9"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[1] # Prints the second element"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "9"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[-2] # Prints the second element"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Slicing\n",
    "\n",
    "You can access sub-lists through the colon operator. This process is called slicing."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[14, 27, 21]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = [10, 7, 14, 27, 21]\n",
    "a[2:] # Prints everything to the right of 14 and includes 14"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[10, 7, 14]"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[:3] # Prints everything to the left of 27"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[14, 27]"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[2:4] # Prints sub-lists containing second and third index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[14, 27]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[2:-1] # Same output as above"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Methods\n",
    "\n",
    "The symbol + and * are concatenation operators. There are several methods associated with lists."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[10, 7, 14, 10, 7, 14]\n"
     ]
    }
   ],
   "source": [
    "a = [10, 7, 14]\n",
    "a = a*2 # output should be [10, 7, 14, 10, 7, 14]\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[10, 7, 14, 10, 7, 14], [10, 7, 14, 10, 7, 14]]\n"
     ]
    }
   ],
   "source": [
    "c = [a]*2 # Note the difference\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[10, 7, 14, 5, 8, 11]\n"
     ]
    }
   ],
   "source": [
    "a = [10, 7, 14]\n",
    "b = [5, 8, 11]\n",
    "a = a + b # output should be [10, 7, 14, 5, 8, 11]\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(a) #prints the length of the list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[10, 7, 14, 5, 8, 11, 20]"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.append(20) #Adds 20 to the end of the list\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[10, 7, 14, 5, 8, 11]"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.pop() # Deletes the last element\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[11, 8, 5, 14, 7, 10]"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.reverse() # reverses the list\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[5, 7, 8, 10, 11, 14]"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.sort() #sorts the list\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[5, 7, 8, 10, 14]"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.remove(11) # removes 11\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "20 in a # Returns a boolean value for the check if element 20 is in list b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "10 in a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "range(start, stop, stepsize) can be used to generate a sequence of numbers. list(range(start, stop, stepsize)) can be used to create a list comprising from the sequence. Note that the number corresponding to stop is not a part of the list. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[10, 12, 14, 16, 18]"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = list(range(10,20,2))\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can create lists of non-integer objects also."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Nashville', 'Austin', 'Pittsburgh']"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cities= [\"Nashville\", \"Austin\", \"Pittsburgh\"]\n",
    "cities"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Lists can contain objects of different type."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[5, 6, 'seven', 8, 9]"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d = [5, 6, \"seven\", 8, 9]\n",
    "d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[5, 6, 8, 9]"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "del d[2] #removes the third element\n",
    "d"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### References\n",
    "\n",
    "Lists are a collection of references to Python data objects."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a =  [5, 8, 12]\n",
      "b =  [5, 8, 12]\n",
      "a =  [5, 8, 12, 4]\n",
      "b =  [5, 8, 12, 4]\n"
     ]
    }
   ],
   "source": [
    "a = [5, 8 , 12]\n",
    "b = a\n",
    "print(\"a = \", a) # output is [5, 8, 12]\n",
    "print(\"b = \", b) # output is [5, 8, 12]\n",
    "a.append(4)\n",
    "print(\"a = \", a) # output is [5, 8, 12, 4]\n",
    "print(\"b = \", b) # output is [5, 8, 12, 4]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When we run the command"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "a = [5, 8 , 12]\n",
    "b = a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We are essentially creating two references."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![List and  References](VariableMemory2.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a =  [5, 8, 12, 4]\n",
      "b =  [5, 8, 12, 4]\n"
     ]
    }
   ],
   "source": [
    "a.append(4)\n",
    "print(\"a = \", a)\n",
    "print(\"b = \", b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![List and  References](VariableMemory3.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can use the slicing operator to make independent copies."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a =  [5, 8, 12]\n",
      "b =  [5, 8, 12]\n",
      "a =  [5, 8, 12, 4]\n",
      "b =  [5, 8, 12]\n"
     ]
    }
   ],
   "source": [
    "a = [5, 8 , 12]\n",
    "b = a[:]\n",
    "print(\"a = \", a) # output is [5, 8, 12]\n",
    "print(\"b = \", b) # output is [5, 8, 12]\n",
    "a.append(4)\n",
    "print(\"a = \", a) # output is [5, 8, 12, 4]\n",
    "print(\"b = \", b) # output is [5, 8, 12]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Another way is to use the deepcopy command."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a =  [5, 8, 12]\n",
      "b =  [5, 8, 12]\n",
      "a =  [5, 8, 12, 4]\n",
      "b =  [5, 8, 12]\n"
     ]
    }
   ],
   "source": [
    "from copy import deepcopy\n",
    "a = [5, 8 , 12]\n",
    "b = deepcopy(a)\n",
    "print(\"a = \", a) # output is [5, 8, 12]\n",
    "print(\"b = \", b) # output is [5, 8, 12]\n",
    "a.append(4)\n",
    "print(\"a = \", a) # output is [5, 8, 12, 4]\n",
    "print(\"b = \", b) # output is [5, 8, 12]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Lists can be two dimensional."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[11, 12, 13]"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "twodlist = [[1, 2, 3],[11, 12, 13],[21, 22, 23]]\n",
    "twodlist[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "12"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "twodlist[1][1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Similarly, we can define three, four, or five dimensional lists. Be careful, when you use * to create two D lists as you are creating references and not copies"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1, 2], [1, 2], [1, 2]]\n"
     ]
    }
   ],
   "source": [
    "b = [1,2]\n",
    "A = [b]*3\n",
    "print(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[5, 3], [5, 3], [5, 3]]\n"
     ]
    }
   ],
   "source": [
    "b[0] = 5\n",
    "A[0][1] = 3\n",
    "print(A)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pay close attention to how the list A has changed."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Tuples and Dictionaries\n",
    "\n",
    "Tuples are like lists but with two main differences:\n",
    "\n",
    "* You cannot change or delete elements of a tuple once created. Tuples are immutable objects.\n",
    "* Tuples use parenthesis whereas lists use square brackets.\n",
    "\n",
    "Tuples are faster than lists. However, the speed gains might not be significant for our applications. Therefore, stick to lists whenever possible."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3, 8, 11, 7)"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "e = (3, 8, 11, 7) # creates a tuple\n",
    "e"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "11"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "e[2] # we use square brackets to access elements of tuples"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'tuple' object does not support item assignment",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-35-6b879ed945e7>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0me\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m12\u001b[0m \u001b[1;31m# There should be an error message\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: 'tuple' object does not support item assignment"
     ]
    }
   ],
   "source": [
    "e[2] = 12 # There should be an error message"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Dictionaries can be used to create maps or unordered collection of objects in Python. In dictionaries, keys are associated with values. The keys are separated from their values using colon. Each key-value item is separated using comma."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "pop = {'Nashville': 200, 'Austin': 500, 'Pittsburgh': 300} "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_keys(['Nashville', 'Austin', 'Pittsburgh'])"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pop.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_values([200, 500, 300])"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pop.values()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The keys and values can be converted to lists using list() function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Nashville', 'Austin', 'Pittsburgh']"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(pop.keys())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "200"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pop['Nashville']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'Austin' in pop"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Python For Loops"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For loops can be used to iterate over elements in lists, tuples, or dictionaries. Indents used to identify code blocks."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "9\n",
      "25\n",
      "49\n"
     ]
    }
   ],
   "source": [
    "a = [1, 3, 5, 7]\n",
    "for i in a: # For each element in list a\n",
    "    print(i*i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "20\n",
      "22\n",
      "24\n",
      "26\n",
      "28\n"
     ]
    }
   ],
   "source": [
    "for i in range(20, 30):\n",
    "    if (i % 2 == 0):\n",
    "        print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For loops can be nested."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10\n",
      "11\n",
      "12\n",
      "13\n",
      "14\n",
      "20\n",
      "22\n",
      "24\n",
      "26\n",
      "28\n",
      "30\n",
      "33\n",
      "36\n",
      "39\n",
      "42\n",
      "40\n",
      "44\n",
      "48\n",
      "52\n",
      "56\n"
     ]
    }
   ],
   "source": [
    "for i in range(1, 5):\n",
    "    for j in range(10,15):\n",
    "        print(i*j) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When you are dealing with non-numeric lists or list lengths which keep changing during implementation you can use range(len(listname))."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 Nashville\n",
      "1 Austin\n",
      "2 Morgantown\n",
      "3 Portland\n"
     ]
    }
   ],
   "source": [
    "cities = [\"Nashville\", \"Austin\", \"Morgantown\", \"Portland\"]\n",
    "for i in range(len(cities)):\n",
    "    print(i,cities[i])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Another way is using enumerate."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 Nashville\n",
      "1 Austin\n",
      "2 Morgantown\n",
      "3 Portland\n"
     ]
    }
   ],
   "source": [
    "cities = [\"Nashville\", \"Austin\", \"Morgantown\", \"Portland\"]\n",
    "for num, name in enumerate(cities):\n",
    "    print(num, name)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you want the index to start from a number other than 0."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 Nashville\n",
      "2 Austin\n",
      "3 Morgantown\n",
      "4 Portland\n"
     ]
    }
   ],
   "source": [
    "cities = [\"Nashville\", \"Austin\", \"Morgantown\", \"Portland\"]\n",
    "for num, name in enumerate(cities, 1):\n",
    "    print(num, name)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The zip command can be used to pairwise merge lists of equal lengths."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(1, 10), (2, 11), (3, 12)]\n"
     ]
    }
   ],
   "source": [
    "a = [1, 2, 3]\n",
    "b = [10, 11, 12]\n",
    "c = zip(a,b)\n",
    "print(list(c))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you want to go through two lists in a for loop."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Nashville 200\n",
      "Austin 500\n",
      "Morgantown 100\n",
      "Portland 400\n"
     ]
    }
   ],
   "source": [
    "cities = [\"Nashville\", \"Austin\", \"Morgantown\", \"Portland\"]\n",
    "population = [200, 500, 100, 400]\n",
    "for name, popul in zip(cities,population):\n",
    "    print(name, popul)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In dictionaries, the default is to iterate through the keys."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Nashville\n",
      "Austin\n",
      "Pittsburgh\n"
     ]
    }
   ],
   "source": [
    "pop = {'Nashville': 200, 'Austin': 500, 'Pittsburgh': 300} \n",
    "for i in pop:\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "200\n",
      "500\n",
      "300\n"
     ]
    }
   ],
   "source": [
    "for i in pop.values():\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Nashville 200\n",
      "Austin 500\n",
      "Pittsburgh 300\n"
     ]
    }
   ],
   "source": [
    "for i,j in pop.items():\n",
    "    print(i,j)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For loops and conditional expressions can be used to create lists conveniently. This is called list comprehension."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 2]"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = [i for i in range(3)]\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[20, 40, 50]"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = [i*2 for i in [10, 20, 25]]\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[1, 10],\n",
       " [1, 11],\n",
       " [1, 12],\n",
       " [2, 10],\n",
       " [2, 11],\n",
       " [2, 12],\n",
       " [3, 10],\n",
       " [3, 11],\n",
       " [3, 12]]"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = [[i,j] for i in [1, 2, 3] for j in [10, 11, 12]]\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 2, 4]"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = [i for i in range(5) if(i%2 == 0)]\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[20, 25, 50]"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c = [20, 10, 50]\n",
    "d = [ 5, 25, 40]\n",
    "e = [max(i) for i in zip(c,d)]\n",
    "e"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
