{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1.1 Python 基础"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.1 Python 简介\n",
    "\n",
    "<img src=\"https://www.python.org/static/img/python-logo@2x.png\" width=300/> \n",
    "\n",
    "**Python** 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。\n",
    "\n",
    "- **Python** 是一种解释型语言： 开发过程中没有了编译这个环节。\n",
    "\n",
    "- **Python** 是交互式语言： 可以在一个 **Python** 提示符 `>>>` 后直接执行代码。\n",
    "\n",
    "- **Python** 是面向对象语言: **Python** 支持面向对象的风格或代码封装在对象的编程技术。\n",
    "\n",
    "- **Python** 对初学者非常友好：**Python** 语法简单，可以快速上手，但异常强大，应用也十分广泛，从 `web` 开发，网络爬虫到机器学习，人工智能，金融量化分析都有广泛的应用。\n",
    " \n",
    "### 第一行 Python 代码"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print (\"hello world!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.2 数据类型\n",
    "\n",
    "| 类型| 例子|\n",
    "| -----  | ----- |\n",
    "| 整数 | `-100` |\n",
    "| 浮点数 | `3.1416` |\n",
    "| 字符串 | `'hello'` |\n",
    "| 列表 | `[1, 1.2, 'hello']` |\n",
    "| 字典 | `{'dogs': 5, 'pigs': 3}`|\n",
    "| 长整型 | `1000000000000L`\n",
    "| 布尔型 | `True, False`\n",
    "| 元组 | `('ring', 1000)`\n",
    "| 集合 | `{1, 2, 3}`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用`type()`函数来查看变量类型："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 1\n",
    "type(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在 **Python** 中运算是有优先级的，优先级即算术的先后顺序，比如“先乘除后加减”和“先算括号里面的”都是两种优先级的规则，优先级从高到低排列如下：\n",
    "\n",
    "- `( )` 括号\n",
    "- `**` 幂指数运算\n",
    "- `* / // %` 乘，除，整数除法，取余运算\n",
    "- `+ -` 加减\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 4\n",
    "b = 3\n",
    "print(\"加:\", a + b)\n",
    "print(\"减:\", a - b)\n",
    "print(\"乘：\", a * b)\n",
    "print(\"除：\", a / b)\n",
    "print('幂：', a ** b)\n",
    "print('取余', a % b)\n",
    "print('取商：', a // b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 常见的数学函数\n",
    "\n",
    "绝对值："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "abs(-12.4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "保留小数点位数:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "round(21.6445, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最大最小值："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print (min(2, 3, 4, 5))\n",
    "print (max(2, 4, 3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 类型转换  \n",
    "浮点数转整型，只保留整数部分："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print (int(-3.32))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "整型转浮点型："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print (float(1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.3 字符串"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用一对单引号`' '`或者双引号`\" \"`生成字符串。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "s = \"hello, world\"\n",
    "print (s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "s = 'hello, world'\n",
    "print (s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 常见的操作\n",
    "\n",
    "**加法**："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 'hello'\n",
    "b = 'world'\n",
    "a + b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**乘法**："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "c = a * 3\n",
    "c"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**分割**:  \n",
    "`s.split()` 将字符串 s 按照空格（包括多个空格，制表符`\\t`，换行符`\\n`等）分割，并返回所有分割得到的字符串。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "line = \"1 2 3 4  5\"\n",
    "numbers = line.split()\n",
    "print (numbers)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**连接**：  \n",
    "与分割相反，`s.join(sequence)` 的作用是以 `s` 为连接符将序列 `sequence` 中的元素连接起来，并返回连接后得到的新字符串。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "s = ' '\n",
    "s.join(numbers)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**替换**：  \n",
    "`s.replace(part1, part2)` 将字符串 `s` 中指定的部分 `part1` 替换成想要的部分 `part2`，并返回新的字符串。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "s = \"hello world\"\n",
    "s.replace('world', 'python')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**大小写转换**：  \n",
    "\n",
    "`s.upper()` 方法返回一个将 `s` 中的字母全部大写的新字符串。\n",
    "\n",
    "`s.lower()` 方法返回一个将 `s` 中的字母全部小写的新字符串。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\"hello world\".upper()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "s = \"HELLO WORLD\"\n",
    "print (s.lower())\n",
    "\n",
    "# 不会改变原来s的值\n",
    "print (s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**字符串的长度**："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "len(s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.4 索引和分片\n",
    "\n",
    "### 索引\n",
    "\n",
    "对于一个有序序列，可以通过索引的方法来访问对应位置的值。字符串便是一个有序序列，**Python** 使用 **下标** 来对有序序列进行索引。索引是从 `0` 开始的，所以索引 `0` 对应与序列的第 `1` 个元素。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "s = \"hello\"\n",
    "s[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "除了正向索引，**Python** 还引入了负索引值的用法，即从后向前开始计数，例如，索引 `-1` 表示倒数第 `1` 个元素："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "s[-1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "单个索引大于等于字符串的长度时，会报错："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "s[6]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 分片  \n",
    "\n",
    "分片用来从序列中提取出想要的子序列，其用法为：  \n",
    "\n",
    "    var[start_index:  stop_index:  step]  \n",
    "\n",
    "其范围包括 `start_index` ，但不包括 `stop_index` ，即 `[start_index, stop_index)`， `step` 表示取值间隔大小，如果没有默认为`1`。  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "s = \"hello\"\n",
    "s[::2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.5 列表\n",
    "\n",
    "列表是一个有序的序列。\n",
    "\n",
    "列表用一对 `[ ]` 生成，中间的元素用 `,` 隔开，其中的元素不需要是同一类型，同时列表的长度也不固定。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "l = [1, 2.0, 'hello']\n",
    "print (l)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "空列表可以用 `[]` 或者 `list()` 生成："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "empty_list = []\n",
    "empty_list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "empty_list = list()\n",
    "empty_list\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 列表的常见操作\n",
    "\n",
    " **长度**：用 `len` 查看列表长度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "l = [1, 2.0, 'hello']\n",
    "len(l)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**加法**: 相当于将两个列表按顺序连接"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [1, 2, 3]\n",
    "b = [3.2, 'hello']\n",
    "a + b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**乘法**：列表与整数相乘，相当于将列表重复相加"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a * 3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###  索引和分片\n",
    "列表和字符串一样可以通过索引和分片来查看它的元素。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**索引**："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [10, 11, 12, 13, 14]\n",
    "a[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**反向索引**："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a[-1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**分片**："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a[2:-1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### **添加元素**\n",
    "\n",
    "**append**：向列表添加单个元素  \n",
    "`l.append(ob)` 将元素 `ob` 添加到列表 `l` 的最后。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [10, 11, 12]\n",
    "a.append(11)\n",
    "print (a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`append` 每次只添加一个元素，并不会因为这个元素是序列而将其展开："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [10, 11, 12]\n",
    "a.append(['a', 'b'])\n",
    "print (a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**extend**: 向列表添加序列元素    \n",
    "`l.extend(lst)` 将序列 `lst` 的元素依次添加到列表 `l` 的最后，作用相当于 `l += lst`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [10, 11, 12]\n",
    "a.extend(['a', 'b'])\n",
    "print (a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**insert**: 插入元素       \n",
    "`l.insert(idx, ob)` 在索引 `idx` 处插入 `ob` ，之后的元素依次后移。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [10, 11, 12, 13, 11]\n",
    "# 在索引 3 插入 'a'\n",
    "a.insert(3, 'a')\n",
    "print (a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### **删除元素** "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**del**：根据下标进行删除"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 根据下标进行删除\n",
    "a = [1002, 'a', 'b', 'c']\n",
    "del a[0]\n",
    "print (a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**pop**：弹出元素    \n",
    "`l.pop(idx)` 会将索引 `idx` 处的元素删除，并返回这个元素。未指定 `idx` 时，默认为列表最后一个元素。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [1002, 'a', 'b', 'c']\n",
    "a.pop()\n",
    "print (a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**remove**：根据元素的值进行删除     \n",
    "`l.remove(ob)` 会将列表中第一个出现的 `ob` 删除，如果 `ob` 不在 `l` 中会报错。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [1002, 'a', 'b', 'c', 'b']\n",
    "a.remove(\"b\")\n",
    "print (a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### **测试从属关系**\n",
    "用 `in` 来看某个元素是否在某个序列（不仅仅是列表）中；\n",
    "\n",
    "用`not in`来判断是否不在某个序列中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [10, 11, 12, 13, 14]\n",
    "print (10 in a)\n",
    "print (10 not in a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "用 `index` 查找某个元素在列表中的位置：\n",
    "\n",
    "`l.index(ob)` 返回列表中元素 `ob` 第一次出现的索引位置，如果 `ob` 不在 `l` 中会报错。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [11, 12, 13, 12, 11]\n",
    "a.index(12)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`count` 查找列表中某个元素出现的次数："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [11, 12, 13, 12, 11]\n",
    "a.count(11)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### **修改元素**  \n",
    "\n",
    "修改元素的时候，要通过下标来确定要修改的是哪个元素，然后才能进行修改"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [10, 11, 12, 13, 11]\n",
    "a[0] = \"a\"\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### **排序**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`sort`方法将 `list` 按特定顺序重新排列，默认为由小到大，参数 `reverse=True` 可改为倒序，由大到小"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 从小到大排序\n",
    "a = [10, 1, 11, 13, 11, 2]\n",
    "a.sort()\n",
    "print (a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 从大到小排序\n",
    "a = [10, 1, 11, 13, 11, 2]\n",
    "a.sort(reverse=True)\n",
    "print (a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果不想改变原来列表中的值，可以使用 `sorted` 函数："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [10, 1, 11, 13, 11, 2]\n",
    "b = sorted(a)\n",
    "print (\"a:\",a)\n",
    "print (\"b:\",b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 列表反向"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`l.reverse()` 会将列表中的元素从后向前排列。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [10, 1, 11, 13, 11, 2]\n",
    "a.reverse()\n",
    "print (a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果不想改变原来列表中的值，可以使用分片："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [10, 1, 11, 13, 11, 2]\n",
    "b = a[::-1]\n",
    "print (\"a:\",a)\n",
    "print (\"b:\",b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.6 字典\n",
    "\n",
    "字典 `dictionary` ，在一些编程语言中也称为 `hash` ， `map` ，是一种由键值对组成的数据结构。\n",
    "\n",
    "顾名思义，我们把键想象成字典中的单词，值想象成词对应的定义，那么——\n",
    "\n",
    "一个词可以对应一个或者多个定义，但是这些定义只能通过这个词来进行查询。\n",
    "\n",
    "**Python** 使用`key: value`这样的结构来表示字典中的元素结构。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 空字典\n",
    "\n",
    "**Python** 使用 `{}` 或者 `dict()` 来创建一个空的字典："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = {}\n",
    "type(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = dict()\n",
    "type(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 插入键值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a[\"one\"] = \"this is number 1\"\n",
    "a[\"two\"] = \"this is number 2\"\n",
    "a[\"three\"] = \"this is number 3\"\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**注意：**  \n",
    "1.字典的键必须是数字、字符串、元组等，不能是列表、字典、集合。  \n",
    "2.字典没有顺序：当我们 `print` 一个字典时，**Python** 并不一定按照插入键值的先后顺序进行显示，因为字典中的键本身不一定是有序的。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 查看键值\n",
    "a['one']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 更新键值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a[\"one\"] = \"this is number 1, too\"\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `get`方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "用键可以找到该键对应的值，但是当字典中没有这个键的时候，**Python** 会报错，这时候可以使用字典的 `get` 方法来处理这种情况，其用法如下：\n",
    "\n",
    "`d.get(key, default = None)`\n",
    "\n",
    "返回字典中键 `key` 对应的值，如果没有这个键，返回 `default` 指定的值（默认是 `None` ）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = {}\n",
    "a[\"one\"] = \"this is number 1\"\n",
    "a[\"two\"] = \"this is number 2\"\n",
    "\n",
    "a.get(\"three\", \"undefined\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `keys` 方法，`values` 方法和`items` 方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`d.keys()` ：返回一个由所有键组成的列表；\n",
    "\n",
    "`d.values()` ：返回一个由所有值组成的列表；\n",
    "\n",
    "`d.items()` ：返回一个由所有键值对元组组成的列表。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = {}\n",
    "a[\"one\"] = \"this is number 1\"\n",
    "a[\"two\"] = \"this is number 2\"\n",
    "\n",
    "a.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a.values()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a.items()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.7 元组\n",
    "\n",
    "元组`Tuple`也是个有序序列，但是元组是不可变的，用`()`生成。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 生成元组\n",
    "a = ()\n",
    "type(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "生成只含有单个元素的元组时,采用下列方式定义："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 生成元组\n",
    "a = (1,)\n",
    "type(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "元组是**不可变**的,修改元组元素时会报错："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = (10, 11, 12, 13, 14)\n",
    "a[0] = 1\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.8 集合"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "之前看到的列表和字符串都是一种有序序列，而集合 `set` 是一种无序的序列。\n",
    "\n",
    "因为集合是无序的，所以当集合中存在两个同样的元素的时候，**Python** 只会保存其中的一个（唯一性）；同时为了确保其中不包含同样的元素，集合中放入的元素只能是不可变的对象（确定性）。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以用`set()`函数来显示的生成空集合："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = set()\n",
    "type(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "也可以使用一个列表来初始化一个集合："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = set([1, 2, 3, 1])\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "集合会自动**去除重复元素** `1`。\n",
    "\n",
    "可以看到，集合中的元素是用大括号`{}`包含起来的，这意味着可以用`{}`的形式来创建集合："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = {1, 2, 3, 1}\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "但是创建空集合的时候只能用`set`来创建，因为在 **Python** 中`{}`创建的是一个空的字典："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "s = {}\n",
    "type(s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.9 判断语句"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 基本用法\n",
    "\n",
    "判断，基于一定的条件，决定是否要执行特定的一段代码，例如判断一个数是不是正数："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 0.5\n",
    "if x > 0:\n",
    "    print (\"Hey!\")\n",
    "    print (\"x is positive\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在这里，如果 `x > 0` 为 `False`即`x ≤ 0` ，那么程序将不会执行两条 `print` 语句。\n",
    "\n",
    "虽然都是用 `if` 关键词定义判断，但与 **C，Java** 等语言不同，**Python**不使用 `{}` 将 `if` 语句控制的区域包含起来。**Python** 使用的是缩进方法。同时，也不需要用 `()` 将判断条件括起来。\n",
    "\n",
    "上面例子中的这两条语句：\n",
    "\n",
    "```python\n",
    "\n",
    "print(\"Hey!\")   \n",
    "print(\"x is positive\")\n",
    "\n",
    "```\n",
    "\n",
    "就叫做一个代码块，同一个代码块使用同样的缩进值，它们组成了这条 `if` 语句的主体。\n",
    "\n",
    "不同的缩进值表示不同的代码块，例如：\n",
    "\n",
    "`x > 0` 时："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 0.5\n",
    "if x > 0:\n",
    "    print (\"Hey!\")\n",
    "    print (\"x is positive\")\n",
    "    print (\"This is still part of the block\")\n",
    "print (\"This isn't part of the block, and will always print.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`x < 0` 时："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = -0.5\n",
    "if x > 0:\n",
    "    print (\"Hey!\")\n",
    "    print (\"x is positive\")\n",
    "    print (\"This is still part of the block\")\n",
    "print (\"This isn't part of the block, and will always print.\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在这两个例子中，最后一句并不是 `if` 语句中的内容，所以不管条件满不满足，它都会被执行。\n",
    "\n",
    "一个完整的 `if` 结构通常如下所示（注意：条件后的 `:` 是必须要的，缩进值需要一样）：\n",
    "    \n",
    "    if <condition 1>:\n",
    "        <statement 1>\n",
    "        <statement 2>\n",
    "    elif <condition 2>: \n",
    "        <statements>\n",
    "    else:\n",
    "        <statements>\n",
    "\n",
    "当条件 1 被满足时，执行 `if` 下面的语句，当条件 1 不满足的时候，转到 `elif` ，看它的条件 2 满不满足，满足执行 `elif` 下面的语句，不满足则执行 `else` 下面的语句。\n",
    "\n",
    "对于上面的例子进行扩展："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 0\n",
    "if x > 0:\n",
    "    print (\"x is positive\")\n",
    "elif x == 0:\n",
    "    print (\"x is zero\")\n",
    "else:\n",
    "    print (\"x is negative\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`elif` 的个数没有限制，可以是1个或者多个，也可以没有。\n",
    "\n",
    "`else` 最多只有1个，也可以没有。\n",
    "\n",
    "可以使用 `and` ， `or` ， `not` 等关键词结合多个判断条件："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 10\n",
    "y = -5\n",
    "x > 0 and y < 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "not x > 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x < 0 or y < 0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这里使用这个简单的例子，假如想判断一个年份是不是闰年，按照闰年的定义，这里只需要判断这个年份是不是能被 `4` 整除，但是不能被 `100` 整除，或者正好被 `400` 整除："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "year = 1900\n",
    "if year % 400 == 0:\n",
    "    print (\"This is a leap year!\")\n",
    "# 两个条件都满足才执行\n",
    "elif year % 4 == 0 and year % 100 != 0:\n",
    "    print (\"This is a leap year!\")\n",
    "else:\n",
    "    print (\"This is not a leap year.\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 判断条件为 `False` 情况总结:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Python** 不仅仅可以使用布尔型变量作为条件，它可以直接在 `if` 中使用任何表达式作为条件：\n",
    "\n",
    "大部分表达式的值都会被当作 `True`，但以下表达式值会被当作 `False`：\n",
    "\n",
    "- False\n",
    "- None\n",
    "- 0\n",
    "- 空字符串，空列表，空字典，空集合"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mylist = [3, 1, 4, 1, 5, 9]\n",
    "if mylist:\n",
    "    print (\"The first element is:\", mylist[0])\n",
    "else:\n",
    "    print (\"There is no first element.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "修改为空列表："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mylist = []\n",
    "if mylist:\n",
    "    print (\"The first element is:\", mylist[0])\n",
    "else:\n",
    "    print (\"There is no first element.\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.10 循环\n",
    "\n",
    "循环的作用在于将一段代码重复执行多次。\n",
    "\n",
    "### `while` 循环"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "    while <condition>:\n",
    "        <statesments>\n",
    "**Python** 会循环执行`<statesments>`，直到`<condition>`不满足为止。\n",
    "\n",
    "例如，计算数字`0`到`100`的和："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "i = 0\n",
    "\n",
    "# 求和结果\n",
    "total = 0\n",
    "\n",
    "# 循环条件\n",
    "while i < 100:\n",
    "    \n",
    "    # 求和累加\n",
    "    total += i\n",
    "    \n",
    "    # 变量递增\n",
    "    i += 1\n",
    "    \n",
    "# 打印结果\n",
    "print (total)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "之前提到，空容器会被当成 `False` ，因此可以用 `while` 循环来读取容器中的所有元素："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plays = ['Hamlet', 'Macbeth', 'King Lear']\n",
    "while plays:\n",
    "    play = plays.pop()\n",
    "    print ('Perform', play)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "循环每次从 `plays` 中弹出一个元素，一直到 `plays` 为空为止。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `for` 循环  \n",
    "\n",
    "    for <variable> in <sequence>:\n",
    "        <indented block of code>\n",
    "\n",
    "`for` 循环会遍历完`<sequence>`中所有元素为止\n",
    "\n",
    "上一个例子可以改写成如下形式："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plays = ['Hamlet', 'Macbeth', 'King Lear']\n",
    "for play in plays:\n",
    "    print ('Perform', play)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用 `for` 循环时，注意尽量不要改变 `plays` 的值，否则可能会产生意想不到的结果。\n",
    "\n",
    "之前的求和也可以通过 `for` 循环来实现："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "total = 0\n",
    "for i in range(100):\n",
    "    total += i\n",
    "print (total)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `continue` 语句\n",
    "\n",
    "遇到 `continue` 的时候，程序会返回到循环的最开始重新执行。\n",
    "\n",
    "例如在循环中忽略一些特定的值："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "values = [7, 6, 4, 7, 19, 2, 1]\n",
    "for i in values:\n",
    "    if i % 2 != 0:\n",
    "        # 忽略奇数\n",
    "        continue\n",
    "    print (i/2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `break` 语句  \n",
    "\n",
    "遇到 `break` 的时候，程序会跳出循环，不管循环条件是不是满足："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "command_list = ['start',\n",
    "                'process',\n",
    "                'process',\n",
    "                'process',\n",
    "                'stop',\n",
    "                'start',\n",
    "                'process',\n",
    "                'stop']\n",
    "while command_list:\n",
    "    command = command_list.pop(0)\n",
    "    if command == 'stop':\n",
    "        break\n",
    "    print(command)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在遇到第一个 `'stop'` 之后，程序跳出循环。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `else` 语句\n",
    "\n",
    "与 `if` 一样， `while` 和 `for` 循环后面也可以跟着 `else` 语句。\n",
    "\n",
    "- 当循环正常结束时，循环条件不满足， `else` 被执行；\n",
    "- 当循环被 `break` 结束时，循环条件仍然满足， `else` 不执行。\n",
    "\n",
    "不执行 `else` 语句："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "values = [7, 6, 4, 7, 19, 2, 1]\n",
    "for x in values:\n",
    "    if x <= 10:\n",
    "        print ('Found:', x)\n",
    "        break\n",
    "else:\n",
    "    print ('All values greater than 10')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "执行 `else` 语句："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "values = [11, 12, 13, 100]\n",
    "for x in values:\n",
    "    if x <= 10:\n",
    "        print ('Found:', x)\n",
    "        break\n",
    "else:\n",
    "    print ('All values greater than 10')\n"
   ]
  }
 ],
 "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.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
