{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2, 3, 4}"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = {1, 2, 3}\t\t\t\t#创建集合并赋值\n",
    "s.add(4)\t\t\t\t#添加元素\n",
    "s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2, 3, 4, 5, 6}"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.update({4, 5, 6})\t\t\t#更新当前集合，自动忽略重复元素\n",
    "s\t\t\t\t\t#输出集合"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2, 3, 4, 6}"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.discard(5)\t\t\t\t#删除元素，不存在则忽略该操作\n",
    "s\t\t\t\t\t#输出集合"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "ename": "KeyError",
     "evalue": "5",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-14-2b699d8d6b24>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0ms\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mremove\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m5\u001b[0m\u001b[1;33m)\u001b[0m                             \u001b[1;31m#删除元素，不存在则抛出异常\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mKeyError\u001b[0m: 5"
     ]
    }
   ],
   "source": [
    "s.remove(5)\t\t\t\t#删除元素，不存在则抛出异常"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 3, 4, 5}\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s= {4,3,5,1}\n",
    "print(s)\n",
    "s.pop()\t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "s"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# dict简单介绍<br/>\n",
    "Python内置了字典：dict的支持，dict全称dictionary，在其他语言中也称为map，使用键-值（key-value）存储，具有极快的查找速度。\n",
    "\n",
    "理解字典后，你就能够更准确地为各种真实物体建模。你可以创建一个表示人的字典，然后想在其中存储多少信息就存储多少信息：<br/>\n",
    "姓名、年龄、地址、职业以及要描述的任何方面。你还能够存储任意两种相关的信息，如一系列单词及其含义，一系列人名及其喜欢的数<br/>\n",
    "字，以及一系列山脉及其海拔等。\n",
    "\n",
    "举个例子，假设要根据同学的名字查找对应的成绩，如果用list实现，需要两个list："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "names = ['Michael', 'Bob', 'Tracy']\n",
    "scores = [95, 75, 85]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'Michael': 95, 'Bob': 75, 'Tracy': 85}"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "key-value存储方式，在放进去的时候，必须根据key算出value的存放位置，这样，取的时候才能根据key直接拿到value。<br/>\n",
    "\n",
    "把数据放入dict的方法，除了初始化时指定外，还可以通过key放入："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "d['Adam'] = 67"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'Michael': 95, 'Bob': 75, 'Tracy': 85, 'Adam': 67}"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "d['Adam'] = 90"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'Michael': 95, 'Bob': 75, 'Tracy': 85, 'Adam': 90}"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果key不存在，dict就会报错："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "ename": "KeyError",
     "evalue": "'aa'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-7-a9b7a0edf285>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0md\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'aa'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mKeyError\u001b[0m: 'aa'"
     ]
    }
   ],
   "source": [
    "d['aa']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "要避免key不存在的错误，有两种办法<br/>\n",
    "**第一种：**是通过in判断key是否存在："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 'Thomas' in d\n",
    "'Adam' in d"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**第二种：**是通过dict提供的get()方法，如果key不存在，可以返回None，或者自己指定的value：<br/>\n",
    "返回None的时候Python的交互环境不显示结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "90"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d.get('Adam',-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'XXXXXXXXXXXXXXXXXXXXXXXXXXX'"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d.get('Thomas', 'XXXXXXXXXXXXXXXXXXXXXXXXXXX')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'Michael': 95, 'Bob': 75, 'Tracy': 85, 'Adam': 90}"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**删除一个key**，用**pop(key)**方法，对应的value也会从dict中删除："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'Michael': 95, 'Tracy': 85, 'Adam': 90}"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d.pop('Bob')\n",
    "d"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "dict内部存放的顺序和key放入的顺序是没有关系的。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 和list比较，dict有以下几个特点：\n",
    "\n",
    "1.查找和插入的速度极快，不会随着key的增加而变慢；<br/>\n",
    "2.需要占用大量的内存，内存浪费多。<br/>\n",
    "**list：**<br/>\n",
    "1.查找和插入的时间随着元素的增加而增加；<br/>\n",
    "2.占用空间小，浪费内存很少。<br/>\n",
    "所以，dict是用空间来换取时间的一种方法。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "dict适合用于高速查找的地方，**dict的key必须是不可变对象**。<br/>\n",
    "这是因为dict根据key来计算value的存储位置，如果每次计算相同的key得出的结果不同，那dict内部就完全混乱了。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "通过key计算位置的算法称为哈希算法（Hash）。**要保证hash的正确性，作为key的对象就不能变。**\n",
    "在Python中，**字符串、整数等**都是不可变的，因此，可以放心地作为key。**list是可变的，就不能作为key:**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "unhashable type: 'list'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-15-c86d5a0c3916>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[0mkey\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m3\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0md\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m'a list'\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      3\u001b[0m \u001b[0md\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mTypeError\u001b[0m: unhashable type: 'list'"
     ]
    }
   ],
   "source": [
    "key = [1, 2, 3]\n",
    "d[key] = 'a list'\n",
    "d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'Michael': 95, 'Tracy': 85, 'Adam': 90, 1: 'number'}"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "key=1\n",
    "d[key]='number'\n",
    "d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1 访问字典中的值**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "You just earned 5 points!\n"
     ]
    }
   ],
   "source": [
    "alien_0 = {'color': 'green', 'points': 5}\n",
    "new_points = alien_0['points']\n",
    "print(\"You just earned \" + str(new_points) + \" points!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2 添加键—值对**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "字典是一种动态结构，可随时在其中添加键—值对。 要添加键—值对，可依次指定字典名、<br/>用\n",
    "方括号括起的键和相关联的值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'color': 'green', 'points': 5}\n",
      "{'color': 'green', 'points': 5, 'x_position': 0, 'y_position': 25}\n"
     ]
    }
   ],
   "source": [
    "alien_0 = {'color': 'green', 'points': 5}\n",
    "print(alien_0)\n",
    "alien_0['x_position'] = 0\n",
    "alien_0['y_position'] = 25\n",
    "print(alien_0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**3 创建空字典**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'color': 'green', 'points': 5}"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alien_0 = {}\n",
    "alien_0['color'] = 'green'\n",
    "alien_0['points'] = 5\n",
    "alien_0 "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**4 修改字典中的值**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The alien is green.\n",
      "The alien is now yellow.\n"
     ]
    }
   ],
   "source": [
    "alien_0 = {'color': 'green'}\n",
    "print(\"The alien is \" + alien_0['color'] + \".\")\n",
    "alien_0['color'] = 'yellow'\n",
    "print(\"The alien is now \" + alien_0['color'] + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Original x-position: 0\n"
     ]
    }
   ],
   "source": [
    "alien_0 = {'x_position': 0, 'y_position': 25, 'speed': 'medium'}\n",
    "print(\"Original x-position: \" + str(alien_0['x_position']))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "New x-position: 5\n"
     ]
    }
   ],
   "source": [
    "# 向右移动外星人\n",
    "# 据外星人当前速度决定将其移动多远\n",
    "if alien_0['speed'] == 'slow':\n",
    "    x_increment = 1\n",
    "elif alien_0['speed'] == 'medium':\n",
    "    x_increment = 2\n",
    "else:\n",
    "    # 这个外星人的速度一定很快\n",
    "    x_increment = 3\n",
    "# 新位置等于老位置加上增量\n",
    "alien_0['x_position'] = alien_0['x_position'] + x_increment\n",
    "print(\"New x-position: \" + str(alien_0['x_position']))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这种技术很棒<br/>例如，要将这个速度中\n",
    "等的外星人变成速度很快的外星人，可添加如下代码行："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "alien_0['speed'] = 'fast'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**5 删除键— 值对**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对于字典中不再需要的信息，可使用del语句将相应的键—值对彻底删除。使用del语句时，<br/>\n",
    "必须指定字典名和要删除的键。\n",
    "例如，下面的代码从字典alien_0中删除键'points'及其值："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'color': 'green', 'points': 5}\n",
      "{'color': 'green'}\n"
     ]
    }
   ],
   "source": [
    "alien_0 = {'color': 'green', 'points': 5}\n",
    "print(alien_0)\n",
    "del alien_0['points']\n",
    "print(alien_0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**6 由类似对象组成的字典**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在前面的示例中，字典存储的是一个对象（游戏中的一个外星人）的多种信息，但你也可以<br/>\n",
    "使用字典来存储众多对象的同一种信息。例如，假设你要调查很多人，询问他们最喜欢的编程语<br/>\n",
    "言，可使用一个字典来存储这种简单调查的结果，如下所示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "favorite_languages = {\n",
    "'jen': 'python',\n",
    "'sarah': 'c',\n",
    "'edward': 'ruby',\n",
    "'phil': 'python',\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Sarah's favorite language is C.\n"
     ]
    }
   ],
   "source": [
    "print(\"Sarah's favorite language is \" + \n",
    "      favorite_languages['sarah'].title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'c'"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "favorite_languages['sarah']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " # 遍历字典"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "一个Python字典可能只包含几个键—值对，也可能包含数百万个键—值对。 鉴于字典可能包含<br/>\n",
    "大量的数据， Python支持对字典遍历。字典可用于以各种方式存储信息，因此有多种遍历字典的<br/>\n",
    "方式：可遍历字典的所有键—值对、键或值。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1 遍历所有的键— 值对**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "user_0 = {\n",
    "'username': 'efermi',\n",
    "'first': 'enrico',\n",
    "'last': 'fermi',\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_items([('username', 'efermi'), ('first', 'enrico'), ('last', 'fermi')])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "user_0.items()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Key: username\n",
      "Value: efermi\n",
      "\n",
      "Key: first\n",
      "Value: enrico\n",
      "\n",
      "Key: last\n",
      "Value: fermi\n"
     ]
    }
   ],
   "source": [
    "# 从字典中同时取两个值\n",
    "for key,value in user_0.items():\n",
    "    print(\"\\nKey: \" + key)\n",
    "    print(\"Value: \" + value)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_items([('username', 'efermi'), ('first', 'enrico'), ('last', 'fermi')])"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "user_0.items()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Jen's favorite language is Python.\n",
      "Sarah's favorite language is C.\n",
      "Edward's favorite language is Ruby.\n",
      "Phil's favorite language is Python.\n"
     ]
    }
   ],
   "source": [
    "favorite_languages = {\n",
    "'jen': 'python',\n",
    "'sarah': 'c',\n",
    "'edward': 'ruby',\n",
    "'phil': 'python',\n",
    "}\n",
    "for name, language in favorite_languages.items():\n",
    "    print(name.title() + \"'s favorite language is \" + language.title() + \".\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2 遍历字典中的所有键**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在不需要使用字典中的值时，方法keys()很有用。下面来遍历字典favorite_languages，<br/>并\n",
    "将每个被调查者的名字都打印出来："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Jen Sarah Edward Phil "
     ]
    }
   ],
   "source": [
    "favorite_languages = {\n",
    "'jen': 'python',\n",
    "'sarah': 'c',\n",
    "'edward': 'ruby',\n",
    "'phil': 'python',\n",
    "}\n",
    "for name in favorite_languages.keys():\n",
    "    print(name.title(),end = ' ')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_keys(['jen', 'sarah', 'edward', 'phil'])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "favorite_languages.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_values(['python', 'c', 'ruby', 'python'])"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "favorite_languages.values()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "favorite_languages['aa']='python'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'jen': 'python',\n",
       " 'sarah': 'c',\n",
       " 'edward': 'ruby',\n",
       " 'phil': 'python',\n",
       " 'aa': 'python'}"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "favorite_languages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('aa', 'python')"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# favorite_languages.popitem(key=='aa')\n",
    "favorite_languages.popitem()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'jen': 'python', 'sarah': 'c', 'edward': 'ruby', 'phil': 'python'}"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "favorite_languages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下面来打印两条消息，指出两位朋友喜欢的语言。<br/>\n",
    "我们像前面一样遍历字典中的名字，但在名字为指定朋友的名字时，<br/>打印一条消息，\n",
    "指出其喜欢的语言："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "favorite_languages = {\n",
    "'jen': 'python',\n",
    "'sarah': 'c',\n",
    "'edward': 'ruby',\n",
    "'phil': 'python',\n",
    "}\n",
    "friends = ['phil', 'sarah']\n",
    "for name in favorite_languages.keys():\n",
    "    print(name.title())\n",
    "    if name in friends:\n",
    "        print(\" Hi \" + name.title() + \", I see your favorite language is \" + favorite_languages[name].title() + \"!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用keys()确定某个人是否接受了调查。下面的代码确定Erin是否接受了调查："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "favorite_languages = {\n",
    "'jen': 'python',\n",
    "'sarah': 'c',\n",
    "'edward': 'ruby',\n",
    "'phil': 'python',\n",
    "}\n",
    "if 'erin' not in favorite_languages.keys():\n",
    "    print(\"Erin, please take our poll!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "方法keys()并非只能用于遍历；实际上，它返回一个列表，其中包含字典中的所有键，因此\n",
    "处的代码行只是核实'erin'是否包含在这个列表中。由于她并不包含在这个列表中，因此打印\n",
    "一条消息，邀请她参加调查"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**3 按顺序遍历字典中的所有键**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "字典总是明确地记录键和值之间的关联关系，但获取字典的元素时，获取顺序是不可预测的。\n",
    "这不是问题，因为通常你想要的只是获取与键相关联的正确的值。\n",
    "要以特定的顺序返回元素，一种办法是在for循环中对返回的键进行排序。为此，可使用函\n",
    "数sorted()来获得按特定顺序排列的键列表的副本："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "favorite_languages = {\n",
    "'jen': 'python',\n",
    "'sarah': 'c',\n",
    "'edward': 'ruby',\n",
    "'phil': 'python',\n",
    "}\n",
    "for name in sorted(favorite_languages.keys()):\n",
    "    print(name.title() + \", thank you for taking the poll.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "**4 遍历字典中的所有值**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果你感兴趣的主要是字典包含的值，可使用方法values()，<br/>它返回一个值列表，而不包含\n",
    "任何键。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The following languages have been mentioned:\n",
      "Python\n",
      "C\n",
      "Ruby\n",
      "Python\n"
     ]
    }
   ],
   "source": [
    "favorite_languages = {\n",
    "'jen': 'python',\n",
    "'sarah': 'c',\n",
    "'edward': 'ruby',\n",
    "'phil': 'python',}\n",
    "print(\"The following languages have been mentioned:\")\n",
    "for language in favorite_languages.values():\n",
    "    print(language.title())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这种做法提取字典中所有的值，而没有考虑是否重复。涉及的值很少时，这也许不是问题，<br/>\n",
    "但如果被调查者很多，最终的列表可能包含大量的重复项。<br/>为剔除重复项，可使用集合（ set）。\n",
    "集合类似于列表，但每个元素都必须是独一无二的："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "favorite_languages = {\n",
    "'jen': 'python',\n",
    "'sarah': 'c',\n",
    "'edward': 'ruby',\n",
    "'phil': 'python',}\n",
    "print(\"The following languages have been mentioned:\")\n",
    "for language in set(favorite_languages.values()):\n",
    "    print(language.title())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 嵌套"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "有时候， 需要将一系列字典存储在列表中，或将列表作为值存储在字典中，这称为嵌套。<br/>你\n",
    "可以在列表中嵌套字典、在字典中嵌套列表甚至在字典中嵌套字典。正如下面的示例将演示的，<br/>\n",
    "嵌套是一项强大的功能。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1 字典列表**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'color': 'green', 'points': 5}\n",
      "{'color': 'yellow', 'points': 10}\n",
      "{'color': 'red', 'points': 15}\n"
     ]
    }
   ],
   "source": [
    "alien_0 = {'color': 'green', 'points': 5}\n",
    "alien_1 = {'color': 'yellow', 'points': 10}\n",
    "alien_2 = {'color': 'red', 'points': 15}\n",
    "aliens = [alien_0, alien_1, alien_2]\n",
    "for alien in aliens:\n",
    "    print(alien)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'color': 'green', 'points': 5, 'speed': 'slow'}\n",
      "{'color': 'green', 'points': 5, 'speed': 'slow'}\n",
      "{'color': 'green', 'points': 5, 'speed': 'slow'}\n",
      "{'color': 'green', 'points': 5, 'speed': 'slow'}\n",
      "{'color': 'green', 'points': 5, 'speed': 'slow'}\n",
      "...\n",
      "Total number of aliens: 30\n"
     ]
    }
   ],
   "source": [
    "# 创建一个用于存储外星人的空列表\n",
    "aliens = []\n",
    "# 创建30个绿色的外星人\n",
    "for alien_number in range(30):\n",
    "    new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}\n",
    "    aliens.append(new_alien)\n",
    "# 显示前五个外星人\n",
    "for alien in aliens[:5]:\n",
    "    print(alien)\n",
    "print(\"...\")\n",
    "# 显示创建了多少个外星人\n",
    "print(\"Total number of aliens: \" + str(len(aliens)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在什么情况下需要处理成群结队的外星人呢？想象一下，可能随着游戏的进行，有些外星人<br/>\n",
    "会变色且移动速度会加快。必要时，我们可以使用for循环和if语句来修改某些外星人的颜色。<br/>\n",
    "例如，要将前三个外星人修改为黄色的、速度为中等且值10个点，可以这样做："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'color': 'yellow', 'points': 10, 'speed': 'medium'}\n",
      "{'color': 'yellow', 'points': 10, 'speed': 'medium'}\n",
      "{'color': 'yellow', 'points': 10, 'speed': 'medium'}\n",
      "{'color': 'green', 'points': 5, 'speed': 'slow'}\n",
      "{'color': 'green', 'points': 5, 'speed': 'slow'}\n",
      "...\n"
     ]
    }
   ],
   "source": [
    "# 创建一个用于存储外星人的空列表\n",
    "aliens = []\n",
    "# 创建30个绿色的外星人\n",
    "for alien_number in range (0,30):\n",
    "    new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}\n",
    "    aliens.append(new_alien)\n",
    "\n",
    "for alien in aliens[0:3]:\n",
    "    if alien['color'] == 'green':\n",
    "        alien['color'] = 'yellow'\n",
    "        alien['speed'] = 'medium'\n",
    "        alien['points'] = 10\n",
    "        \n",
    "# 显示前五个外星人\n",
    "for alien in aliens[0:5]:\n",
    "    print(alien)\n",
    "print(\"...\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "你可以进一步扩展这个循环，在其中添加一个elif代码块，将黄色外星人改为移动速度快且<br/>\n",
    "值15个点的红色外星人，如下所示（这里只列出了循环，而没有列出整个程序）："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 创建一个用于存储外星人的空列表\n",
    "aliens = []\n",
    "# 创建30个绿色的外星人\n",
    "for alien_number in range (0,30):\n",
    "    new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}\n",
    "    aliens.append(new_alien)\n",
    "    \n",
    "for alien in aliens[0:3]:\n",
    "    if alien['color'] == 'green':\n",
    "        alien['color'] = 'yellow'\n",
    "        alien['speed'] = 'medium'\n",
    "        alien['points'] = 10\n",
    "    elif alien['color'] == 'yellow':\n",
    "        alien['color'] = 'red'\n",
    "        alien['speed'] = 'fast'\n",
    "        alien['points'] = 15\n",
    "# 显示前五个外星人\n",
    "for alien in aliens[0:9]:\n",
    "    print(alien)\n",
    "print(\"...\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2 在字典中存储列表**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "有时候， 需要将列表存储在字典中，而不是将字典存储在列表中。<br/>例如，你如何描述顾客点的比萨呢？如果使用列表，\n",
    "<br/>只能存储要添加的比萨配料；但如果使用字典，就不仅可在其中包含\n",
    "配料列表，还可包含其他有关比萨的描述。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "You ordered a thick-crust pizza with the following toppings:\n",
      "\tmushrooms\n",
      "\textra cheese\n"
     ]
    }
   ],
   "source": [
    "# 存储所点比萨的信息\n",
    "pizza = {\n",
    "'crust': 'thick',\n",
    "'toppings': ['mushrooms', 'extra cheese'],\n",
    "}\n",
    "\n",
    "# 概述所点的比萨\n",
    "print(\"You ordered a \" + pizza['crust'] + \"-crust pizza \" +\n",
    "\"with the following toppings:\")\n",
    "\n",
    "for topping in pizza['toppings']:\n",
    "    print(\"\\t\" + topping)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "每当需要在字典中将一个键关联到多个值时，都可以在字典中嵌套一个列表。在本章前面有\n",
    "关喜欢的编程语言的示例中，如果将每个人的回答都存储在一个列表中，被调查者就可选择多种\n",
    "喜欢的语言。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "(Jen)'s favorite languages are:\n",
      "\tPython\n",
      "\tRuby\n",
      "\n",
      "Sarah's favorite languages are:\n",
      "\tC\n",
      "\n",
      "Edward's favorite languages are:\n",
      "\tRuby\n",
      "\tGo\n",
      "\n",
      "Phil's favorite languages are:\n",
      "\tPython\n",
      "\tHaskell\n"
     ]
    }
   ],
   "source": [
    "favorite_languages = {\n",
    "'jen': ['python', 'ruby'],\n",
    "'sarah': ['c'],\n",
    "'edward': ['ruby', 'go'],\n",
    "'phil': ['python', 'haskell'],\n",
    "}\n",
    "\n",
    "for name, languages in favorite_languages.items():\n",
    "    print(\"\\n\" + name.title() + \"'s favorite languages are:\")\n",
    "    for language in languages:\n",
    "        print(\"\\t\" + language.title())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**3 在字典中存储字典**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在下面的程序中，对于每位用户，我们都存储了其三项信\n",
    "息：名、姓和居住地；为访问这些信息，我们遍历所有的用户名，<br/>并访问与每个用户名相关联的\n",
    "信息字典："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "users = {\n",
    "'aeinstein': {\n",
    "'first': 'albert',\n",
    "'last': 'einstein',\n",
    "'location': 'princeton',\n",
    "},\n",
    "'mcurie': {\n",
    "'first': 'marie',\n",
    "'last': 'curie',\n",
    "'location': 'paris',\n",
    "},\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Username: aeinstein\n",
      "\tFull name: Albert Einstein\n",
      "\tLocation: Princeton\n",
      "\n",
      "Username: mcurie\n",
      "\tFull name: Marie Curie\n",
      "\tLocation: Paris\n"
     ]
    }
   ],
   "source": [
    "for username, user_info in users.items():\n",
    "    print(\"\\nUsername: \" + username)\n",
    "    full_name = user_info['first'] + \" \" + user_info['last']\n",
    "    location = user_info['location']\n",
    "    print(\"\\tFull name: \" + full_name.title())\n",
    "    print(\"\\tLocation: \" + location.title())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# set\n",
    "set和dict类似，也是**一组key的集合，但不存储value**。由于key不能重复，**在set中，没有重复的key。**\n",
    "\n",
    "要创建一个set，需要提供一个list作为输入集合：\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2, 3}"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = set([1, 2, 3])\n",
    "s"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "传入的参数[1, 2, 3]是一个list，而显示的{1, 2, 3}只是告诉你这个set内部有1，2，3这3个元素，显示的顺序也不表示set是有序的"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "重复元素在set中自动被过滤："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2, 3}"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = set([1, 1, 2, 2, 3, 3])\n",
    "s"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "通过add(key)方法可以添加元素到set中，可以重复添加，但不会有效果："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2, 3, 4}"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.add(4)\n",
    "s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2, 3, 4}"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.add(4)\n",
    "s"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "通过remove(key)方法可以删除元素："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2, 3}"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.remove(4)\n",
    "s"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "set可以看成数学意义上的无序和无重复元素的集合，因此，两个set可以做数学意义上的交集、并集等操作："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "s1 = set([1, 2, 3])\n",
    "s2 = set([2, 3, 4])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{2, 3}"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s1 & s2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2, 3, 4}"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s1 | s2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "set和dict的唯一区别仅在于没有存储对应的value，但是，set的原理和dict一样，<br/>\n",
    "所以，同样不可以放入可变对象，因为无法判断两个可变对象是否相等，​<br/>\n",
    "也就无法保证set内部“不会有重复元素”。试试把list放入set，看看是否会报错。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 再议不可变对象\n",
    "str是不变对象，而list是可变对象。<br/>\n",
    "对于可变对象，比如list，对list进行操作，list内部的内容是会变化的，比如："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['a', 'b', 'c']"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = ['c', 'b', 'a']\n",
    "a.sort()\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对于不可变对象，比如str:<br/>\n",
    "虽然字符串有个replace()方法，也确实变出了'Abc'，但变量a最后仍是'abc'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'str' 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-44-295be6b6f961>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[0ma\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'abc'\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0ma\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'A'\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      3\u001b[0m \u001b[0ma\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mTypeError\u001b[0m: 'str' object does not support item assignment"
     ]
    }
   ],
   "source": [
    "a='abc'\n",
    "a[0]='A'\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "abc 2610455307744\n",
      "Abc 2610495922840\n",
      "abc 2610455307744\n"
     ]
    }
   ],
   "source": [
    "a = 'abc'\n",
    "print(a,id(a))\n",
    "print(a.replace('a', 'A'),id(a.replace('a', 'A')))\n",
    "print(a,id(a))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Abc'"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = 'abc'\n",
    "b = a.replace('a', 'A')\n",
    "b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "a是变量，而'abc'才是字符串对象！<br/>\n",
    "对象a的内容是'abc'，\n",
    "但其实是指，a本身是一个变量，它指向的对象的内容才是'abc'："
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "┌───┐                  ┌───────┐\n",
    "│ a │─────────────────>│ 'abc' │\n",
    "└───┘                  └───────┘\n",
    "┌───┐                  ┌───────┐\n",
    "│ b │─────────────────>│ 'Abc' │\n",
    "└───┘                  └───────┘\n",
    "调用a.replace('a', 'A')时，实际上调用方法replace是作用在字符串对象'abc'上的，而这个方法虽然名字叫replace，但却没有改变字符串'abc'的内容。相反，replace方法创建了一个新字符串'Abc'并返回，如果我们用变量b指向该新字符串，就容易理解了，变量a仍指向原有的字符串'abc'，但变量b却指向新字符串'Abc'了。"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "对于不变对象来说，调用对象自身的任意方法，也不会改变该对象自身的内容。\n",
    "相反，这些方法会创建新的对象并返回，这样，就保证了不可变对象本身永远是不可变的。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 函数 input()的工作原理"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "函数input()让程序暂停运行，等待用户输入一些文本。获取用户输入后， Python将其存储在\n",
    "一个变量中，以方便你使用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tell me something, and I will repeat it back to you: clever\n",
      "clever\n"
     ]
    }
   ],
   "source": [
    "message = input(\"Tell me something, and I will repeat it back to you: \")\n",
    "print(message)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "If you tell us who you are, we can personalize the messages you see.\n",
      "What is your first name? a\n",
      "\n",
      "Hello, a!\n"
     ]
    }
   ],
   "source": [
    "prompt = \"If you tell us who you are, we can personalize the messages you see.\"\n",
    "prompt += \"\\nWhat is your first name? \"\n",
    "name = input(prompt)\n",
    "print(\"\\nHello, \" + name + \"!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "How old are you? 16\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "age = input(\"How old are you? \")\n",
    "int(age) >= 18"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 使用 while 循环来处理列表和字典"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1 在列表之间移动元素**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "假设有一个列表，其中包含新注册但还未验证的网站用户；验证这些用户后，如何将他们移\n",
    "到另一个已验证用户列表中呢？一种办法是使用一个while循环，在验证用户的同时将其从未验\n",
    "证用户列表中提取出来，再将其加入到另一个已验证用户列表中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 首先，创建一个待验证用户列表\n",
    "# 和一个用于存储已验证用户的空列表\n",
    "unconfirmed_users = ['alice', 'brian', 'candace']\n",
    "confirmed_users = []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 验证每个用户，直到没有未验证用户为止\n",
    "# 将每个经过验证的列表都移到已验证用户列表中\n",
    "while unconfirmed_users:\n",
    "    current_user = unconfirmed_users.pop()\n",
    "    print(\"Verifying user: \" + current_user.title())\n",
    "    confirmed_users.append(current_user)\n",
    "    \n",
    "# 显示所有已验证的用户\n",
    "print(\"\\nThe following users have been confirmed:\")\n",
    "for confirmed_user in confirmed_users:\n",
    "    print(confirmed_user.title())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2 删除包含特定值的所有列表元素**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们使用函数remove()来删除列表中的特定值，这之所以可行，是因为要删除\n",
    "的值在列表中只出现了一次。如果要删除列表中所有包含特定值的元素，该怎么办呢？<br/>\n",
    "假设你有一个宠物列表，其中包含多个值为'cat'的元素。要删除所有这些元素，可不断运\n",
    "行一个while循环，直到列表中不再包含值'cat'，如下所示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "pets = ['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pets.remove('dog')\n",
    "pets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']\n",
      "['dog', 'goldfish', 'rabbit']\n"
     ]
    }
   ],
   "source": [
    "\n",
    "print(pets)\n",
    "while 'cat' in pets:\n",
    "    pets.remove('cat')\n",
    "print(pets)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "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.13"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
