python基础五

这篇博客主要介绍了Python的基础知识,包括对象类型的概念,详细探讨了数字类型,如整型、浮点型等,并解释了Python的动态类型特性。

(1)对象类型


{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. Python 核心数据类型  \n",
    "\n",
    "**内置对象**  \n",
    "\n",
    "对象类型|例子 常量/创建\n",
    "---|---\n",
    "数字|1234, 3.1415, 3+4j, 0b111, Decimal(), Fraction()\n",
    "字符串|'spam', \"guido's\", b'a\\xolc', u'sp\\xc4m'\n",
    "列表|[1, [2, 'three'], 4], list(range(10))\n",
    "字典|{'food': 'spam', 'taste': 'yum'}, dict(hours=10)\n",
    "元组|(1, 'spam', 4, 'U'), tuple('spam'), namedtuple\n",
    "文件|open('eggs.txt'), open(r'C:\\ham.bin', 'wb')\n",
    "集合|set('abc'), {'a', 'b', 'c'}\n",
    "其他类型|类型、None、布尔型\n",
    "编程单元类型|函数、模块、类\n",
    "与实现相关的类型|编译的代码,堆栈跟踪"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. 变量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello World\n"
     ]
    }
   ],
   "source": [
    "message = \"Hello World\"\n",
    "print(message)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这里message为一个变量,与字符串“Hello World”关联在一起。\n",
    "- 变量名只能包含字母、数字和下划线,变量名可以字母或下划线开头,但不能以数字开头。\n",
    "- 变量名不能包含空格,但可以使用下划线分隔其中单词。\n",
    "- 不能将Python关键字和函数名用作函数名。\n",
    "- 变量名应既简短又具有描述性。\n",
    "- 慎用小写字母l和大写字母O。  \n",
    "\n",
    "\n",
    "\n",
    "Python中有三个主要类型(以及操作)的分类:  \n",
    "- 数字(整数、浮点数、二进制、分数等)  \n",
    "    支持加法和乘法等。  \n",
    "- 序列(字符串、列表、元组)  \n",
    "    支持索引、分片和合并等。  \n",
    "- 映射(字典)  \n",
    "    支持通过键的索引等。  \n",
    "\n",
    "Python中主要核心类型划分为如下两类:  \n",
    "- **不可变类型**:数字、字符串、元组、不可变集合  \n",
    "- **可变类型**:列表、字典、可变集合"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "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.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}

(2)python基础 数字类型




{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. Python 的数字类型\n",
    "Python 数字类型的完整工具包括:\n",
    "- 整数和浮点数\n",
    "- 复数\n",
    "- 固定精度的十进制数\n",
    "- 有理分数\n",
    "- 集合\n",
    "- 布尔类型\n",
    "- 无穷的整数精度\n",
    "- 各种数字内置函数和模块"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.1 数字常量(Literals)\n",
    "**基本数字常量**\n",
    "\n",
    "常量|解释\n",
    "---|---\n",
    "1234, -24, 0, 99999999|整数(无穷大小)\n",
    "1.23, 1., 3.14e-10, 4E210, 4.0e+210|浮点数\n",
    "0o177, 0x9ff, 0b101010|八进制、十六进制和二进制常量\n",
    "3+4j, 3.0+4.0j, 3j|复数常量\n",
    "set('spam'), {1, 2, 3, 4}|集合\n",
    "Decimal('1.0'), Fraction(1, 3)|小数和分数扩展类型\n",
    "bool(X), True, False|布尔类型和常数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.2 Python 表达式操作符\n",
    "**Python 表达式操作符和程序**\n",
    "\n",
    "操作符|描述\n",
    "---|---\n",
    "yield x|生成器函数发送协议\n",
    "lambda args: expression|生成匿名函数\n",
    "x if y else z|三元选择表达式\n",
    "x or y|逻辑或(只有 x 为假,才会计算 y)\n",
    "x and y|逻辑与(只有 x 为真,才会计算 y)\n",
    "not x|逻辑非\n",
    "x in y, x not in y|成员关系(可迭代对象、集合)\n",
    "x is y, x is not y|对象实体测试\n",
    "x < y, x <= y, x > y, x >= y|大小比较,集合子集和超集\n",
    "x == y, x != y|值相等性操作符\n",
    "x \\| y|位或,集合并集\n",
    "x ^ y|位异或,集合对称差\n",
    "x & y|位与,集合交集\n",
    "x << y, x >> y|左移或右移 y 位\n",
    "x + y|加法,合并\n",
    "x - y|减法,集合差集\n",
    "x * y|乘法,重复\n",
    "x % y|余数,格式化\n",
    "x / y, x // y|除法:真除法或 floor 除法\n",
    "-x, +x|一元减法,识别\n",
    "~x|按位求补(取反)\n",
    "x ** y|幂运算\n",
    "x[i]|索引(序列、映射及其他)\n",
    "x[i:j:k]|分片\n",
    "x(...)|调用(函数、方法、类及其他可调用的)\n",
    "x.attr|属性引用\n",
    "(...)|元组,表达式,生成器表达式\n",
    "[...]|列表,列表解析\n",
    "{...}|字典、集合、集合和字典解析\n",
    "\n",
    "上表中操作符越靠后的优先级越高。  \n",
    "\n",
    "在混合类型的表达式中,Python 首先将被操作的对象转换成其中最复杂的操作对象的类型,然后再对相同类型的操作对象进行数学运算。整数比浮点数简单,浮点数比复数简单。  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. 在实际应用中的数字\n",
    "## 2.1 变量和基本的表达式\n",
    "\n",
    "在Python中:  \n",
    "- 变量在它第一次赋值时创建。\n",
    "- 变量在表达式中使用将被替换为它们的值。\n",
    "- 变量在表达式中使用以前必须已赋值。\n",
    "- 变量像对象一样不需要在一开始进行声明。\n",
    "\n",
    "在 Python 中,变量并不需要预先声明,但是在使用之前,至少要赋一次值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 3             # 赋值会让变量 a 和 b 自动生成\n",
    "b = 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(4, 12)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a + 1, b * 3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.2 比较:一般的和连续的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1 < 2 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2.0 >= 1     # 大于等于:混合类型 1 转换为 1.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2.0 == 2.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2.0 != 2.0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python 允许我们把多个比较连续起来执行范围测试:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X = 2              \n",
    "Y = 4\n",
    "Z = 6\n",
    "X < Y < Z           # 连续比较,相当于 X < Y and Y < Z"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X < Y > Z           # 相当于 X < Y and Y > Z"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.3 除法:Floor 除法和真除法\n",
    "\n",
    "**X / Y**  \n",
    "真除法,无论任何类型都会保持小数部分。  \n",
    "**X // Y**  \n",
    "Floor 除法,不考虑操作对象的类型,总会省略掉结果的小数部分。  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.5"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "10 / 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "10 // 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.0"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "10 // 4.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-3"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "5 // -2      # 向下舍入"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.4 复数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(-1+0j)"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1j * 1J"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2+3j)"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2 + 1j * 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(6+3j)"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(2 + 1j) * 3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.5 十六进制、八进制、二进制:常量和转换\n",
    "这些常量只是指定一个整数对象的值的一种替代方法。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 16, 255)"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "0o1, 0o20, 0o377          # 八进制常量,数字 0-7"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 16, 255)"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "0x01, 0x10, 0xFF          # 十六进制常量,数字 0-9/A-F"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 16, 255)"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "0b1, 0b10000, 0b11111111  # 二进制常量,数字 0-1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python 默认使用十进制值显示,但它提供了内置的函数,允许把整数转换为其他进制的数字字符串:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('0o100', '0x40', '0b1000000')"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "oct(64), hex(64), bin(64)      # 八进制,十六进制,二进制"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "内置的 `int` 函数可以将一个数字字符串转换为整数,并可以通过定义的第二个参数来指定数字的进制:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(64, 64, 64, 64)"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "64, 0o100, 0x40, 0b1000000"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(64, 64, 64, 64)"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "int('64'), int('100', 8), int('40', 16), int('1000000', 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(64, 64)"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "int('0x40', 16), int('0b1000000', 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以使用字符串格式化方法调用和表达式将一个整数转换为八进制数和十六进制数的字符串:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'100, 40, 1000000'"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'{0:o}, {1:x}, {2:b}'.format(64, 64, 64)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.6 位操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = 1                # 0001\n",
    "x << 2               # 左移两位:0100"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x | 2                # 位或:0011"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x & 1                # 位与:0001"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'0b100'"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X = 0b0001           # 二进制常量\n",
    "bin(X << 2)          # 二进制数字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'0b11'"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bin(X | 0b010)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'0b1'"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bin(X & 0b1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'0b1010101'"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X = 0xFF              # 十六进制数\n",
    "bin(X ^ 0b10101010)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.7 其他的内置数学工具"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3.141592653589793, 2.718281828459045)"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import math\n",
    "math.pi, math.e                     # 通用常数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.03489949670250097"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "math.sin(2 * math.pi / 180)         # sin, tan, cos"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "12.0"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "math.sqrt(144)                      # 平方根"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(16, 16)"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pow(2, 4), 2 ** 4                   # 指数(幂)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(42.0, 10)"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "abs(-42.0), sum((1, 2, 3, 4))       # 绝对值,加和"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 4)"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "min(3, 1, 2, 4), max(3, 1, 2, 4)    # 最小值,最大值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2, -3)"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "math.floor(2.567), math.floor(-2.567)    # 向下取整"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2, -2)"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "math.trunc(2.567), math.trunc(-2.567)    # 截断(去掉小数部分)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3, 2, 2.57)"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "round(2.567), round(2.467), round(2.567, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. 其他数字类型  \n",
    "## 3.1 小数数字\n",
    "小数通过一个导入的模块调用函数后创建,而不是通过运行常量表达式创建。小数对象有固定的位数和小数点,因此有固定的精度。  \n",
    "\n",
    "浮点数学缺乏精确性,因为用来存储数值的空间有限。例如,下面的计算应该得到零,但是结果却没有。结果接近零,但却没有足够的位数去实现这样的精度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5.551115123125783e-17"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "0.1 + 0.1 + 0.1 - 0.3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用小数对象,结果能够改正(接受参数为字符串)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Decimal('0.0')"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from decimal import Decimal\n",
    "Decimal('0.1') + Decimal('0.1') + Decimal('0.1') - Decimal('0.3')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "当不同精度的小数在表达式中混编时,Python 自动升级为小数位数最多的  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Decimal('0.20')"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from decimal import Decimal\n",
    "Decimal('0.1') + Decimal('0.10')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python 也允许直接使用浮点数,转换是精确的,但有时会产生大量的默认数字,除非它们被固定位数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Decimal('2.775557561565156540423631668E-17')"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from decimal import Decimal\n",
    "Decimal(0.1) + Decimal(0.1) + Decimal(0.1) - Decimal(0.3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**设置全局精度**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Decimal('0.1429')"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import decimal\n",
    "decimal.getcontext().prec = 4\n",
    "decimal.Decimal(1) / decimal.Decimal(7)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**小数上下文管理器**  \n",
    "可以使用上下文管理器语句来重新设置临时精度。在语句退出后,精度又重新设置为初始值:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "import decimal\n",
    "with decimal.localcontext() as ctx:\n",
    "    ctx.prec = 2\n",
    "    decimal.Decimal('1.00') / decimal.Decimal('3.00')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.2 分数类型\n",
    "分数类型实现了一个有理数对象,明确保留了一个分子和一个分母,从而避免了浮点数学的某些不精确性和局限性"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Fraction(1, 3)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from fractions import Fraction\n",
    "x = Fraction(1, 3)                       # 分子,分母\n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1/3\n"
     ]
    }
   ],
   "source": [
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Fraction(2, 3)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x + x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Fraction(1, 4)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Fraction('.25')                 # 也可以使用浮点数字符串来创建"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**转换和混合类型**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(5, 2)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(2.5).as_integer_ratio()        # 浮点对象方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Fraction(5, 2)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = Fraction(*2.5.as_integer_ratio())     # 浮点转换为分数,和 Fraction(5, 2) 相同\n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.5"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "float(x)                                  # 分数转换为浮点数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Fraction(7, 4)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Fraction.from_float(1.75)                 # 浮点数转换为分数,另一种方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.3 集合(Set)\n",
    "集合是一些唯一的、不可变的对象的一个无序集合,这些对象支持与数学集合理论相对应的操作。  \n",
    "\n",
    "要创建一个集合对象,需要向内置的set函数传递一个序列或其他的可迭代的对象。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'b', 'd', 'x', 'y', 'z'}"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = set('abcde')\n",
    "# Python 3 允许使用花括号创建集合:{1, 2, 3, 4}\n",
    "y = set('bdxyz')\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "集合通过表达式操作符支持一般的数学集合运算。  \n",
    "\n",
    "不能在一般序列上应用这些表达式,必须通过序列创建集合后才能使用。  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'e' in x            # 成员关系 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a', 'c', 'e'}"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x - y               # 差集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a', 'b', 'c', 'd', 'e', 'x', 'y', 'z'}"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x | y               # 并集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'b', 'd'}"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x & y               # 交集,x.intersection(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a', 'c', 'e', 'x', 'y', 'z'}"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x ^ y               # 对称差(XOR)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(False, False)"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x > y, x < y        # 超子集,子集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'b', 'd'}"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 方法\n",
    "z = x.intersection(y)\n",
    "z"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'SPAM', 'b', 'd'}"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "z.add('SPAM')        # 插入一项\n",
    "z"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'SPAM', 'X', 'Y', 'b', 'd'}"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "z.update(set(['X', 'Y']))       # 融合:原处并集操作\n",
    "z"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'SPAM', 'X', 'Y', 'd'}"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "z.remove('b')                   # 删除一项\n",
    "z"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "集合也可用于 len、for 循环和列表解析,但由于集合是无序的,所以不支持索引和分片这样的操作。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "bbb\n",
      "ccc\n",
      "aaa\n"
     ]
    }
   ],
   "source": [
    "for item in set('abc'):\n",
    "    print(item * 3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "空的集合必须通过内置函数`set()`创建。  \n",
    "\n",
    "集合只能包含不可变的对象类型,因此,列表和字典不能嵌入到集合中,但是元组可以。  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "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-34-40944404bb92>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[0mS\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m{\u001b[0m\u001b[1;36m1.23\u001b[0m\u001b[1;33m}\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mS\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0madd\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[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: unhashable type: 'list'"
     ]
    }
   ],
   "source": [
    "S = {1.23}\n",
    "S.add([1, 2, 3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "unhashable type: 'dict'",
     "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-d6f809fee825>\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[0madd\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m{\u001b[0m\u001b[1;34m'a'\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m}\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: unhashable type: 'dict'"
     ]
    }
   ],
   "source": [
    "S.add({'a': 1})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{(1, 2, 3), 1.23}"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "S.add((1, 2, 3))\n",
    "S"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**集合解析(set comprehension)**  \n",
    "集合解析运行一个循环并在每次迭代时收集一个表达式的结果,通过一个循环变量来访问当前的迭代值以用于集合表达式中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 4, 9, 16}"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "{x ** 2 for x in [1,2,3,4]}    # 对于列表中的每一个 x,给出包含 x 的平方的一个新的集合"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'aaaa', 'mmmm', 'pppp', 'ssss'}"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "{x * 4 for x in 'spam'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.4 布尔型\n",
    "bool,其值为 True 和 False,其值是预先定义的内置的变量名。在内部,新的变量名 True 和 False 是 bool 的实例,实际上仅仅是内置的整数类型 int 的子类。  \n",
    "\n",
    "True 和 False 的行为和整数 1 和 0 是一样的,除了它们有特定的显示逻辑。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "bool"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "isinstance(True, int)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "True == 1               # 值相等"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "True is 1               # 但是是不同对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "True + 4"
   ]
  }
 ],
 "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.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}

(3)动态类型

{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. 缺少类型声明语句的情况\n",
    "在 Python 中,类型是在运行过程中自动决定的,而不是通过代码声明。\n",
    "\n",
    "## 1.1 变量、对象和引用\n",
    "- 变量创建:一个变量,就像 a,当代码第一次给它赋值时就创建了它。之后的赋值将会改变已创建的变量名的值。\n",
    "- 变量类型:变量永远不会有任何和它关联的类型信息或约束。类型的概念是存在于对象中而不是变量名中。\n",
    "- 变量使用:当变量出现在表达式中时,它马上被当前引用的对象所代替,无论这个对象是什么类型。所有的变量必须在其使用前明确地赋值,使用未赋值的变量会产生错误。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "从概念上来说,对 a = 3,Python 将会执行三个不同的步骤去完成请求:\n",
    "1. 创建一个对象来代表值 3。\n",
    "2. 创建一个变量 a,如果它还没有创建的话。\n",
    "3. 将变量与新的对象 3 相连接。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "变量和对象保存在内存中的不同部分,并通过连接相关联。  \n",
    "\n",
    "Python 中从变量到对象的连接称为引用。引用是一种关系,以内存中的指针的形式实现。  \n",
    "\n",
    "- **变量**是一个系统表的元素,拥有指向对象的连接的空间。\n",
    "- **对象**是分配的一块内存,有足够的空间去表示它们所代表的的值。\n",
    "- **引用**是自动形成的从变量到对象的指针。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.2 类型属于对象,而不是变量\n",
    "在 Python 中,变量名没有类型,类型属于对象,而不是变量名。Python 的变量就是在特定的时间引用了一个特定的对象。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 3           # 整数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 'spam'      # 现在是一个字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 1.23        # 现在是一个浮点数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "每个对象都包含了一个头部信息,其中标记了这个对象的类型。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.3 对象的垃圾收集\n",
    "每当一个变量名被赋予了一个新的对象,之前的那个对象占用的空间就会被回收(如果它没有被其他的变量名或对象所引用的话)。这种自动回收对象空间的技术叫做垃圾回收。  \n",
    "\n",
    "在内部,Python 在每个对象中保持了一个计数器,计数器记录了当前指向该对象的引用的数目。一旦(并精确在同一时间)这个计数器被设置为零,这个对象的内存空间就会自动回收。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. 共享引用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 3\n",
    "b = a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "赋值语句 b = a 之后,变量 b 成为对象 3 的一个引用,即 a 和 b 都引用了相同的对象。这叫做共享引用。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = 3\n",
    "b = a\n",
    "a = 'spam'\n",
    "b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对于上例,简单地创建了一个新的对象('spam'),并设置 a 对这个新的对象进行引用。这并不会改变 b 的值,b 仍然引用原始的对象。  \n",
    "\n",
    "<img src='ref.png' width=500px></img>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "给一个变量赋一个新的值,并不是替换了原始的对象,而是让这个变量去引用完全不同的一个对象。当可变对象以及原处改变进入这个场景,那么这个情形会有某种改变。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.1 共享引用和在原处修改\n",
    "对于支持原处修改的对象,共享引用时需要加倍小心,因为对一个变量名的修改会影响其他的变量。  \n",
    "\n",
    "例如列表支持对位置的在原处赋值:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(24, [2, 3, 4])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L1 = [2, 3, 4]\n",
    "L2 = L1\n",
    "L1 = 24\n",
    "L1, L2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "L1 直接设置为一个不同的对象,L2 仍是引用最初的列表。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([24, 3, 4], [24, 3, 4])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L1 = [2, 3, 4]          # 可变对象\n",
    "L2 = L1                 # 创建一个相同对象的引用\n",
    "L1[0] = 24              # 进行原处修改\n",
    "L1, L2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这里改变了 L1 所引用的对象的一个元素。这类修改会覆盖列表对象中的某部分。  \n",
    "\n",
    "因为这个列表对象是与其他对象共享的,那么一个像这样在原处的改变不仅仅会对 L1 有影响。  \n",
    "\n",
    "这种行为仅在支持原处修改的可变对象上发生,如果不想要这样的现象发生,可以拷贝对象,而不是创建引用。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([24, 3, 4], [2, 3, 4])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L1 = [2, 3, 4]\n",
    "L2 = L1[:]              # 创建一个 L1 的拷贝\n",
    "L1[0] = 24\n",
    "L1, L2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这种分片技术不会应用在其他的可变的核心类型(字典和集合)上,复制一个字典或集合应该使用 `X.copy()` 方法调用。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import copy\n",
    "X = copy.copy(Y)          # 创建任意对象 Y 的顶层“浅”拷贝\n",
    "X = copy.deepcopy(Y)      # 创建任意对象 Y 的深拷贝:拷贝所有嵌套部分"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.2 共享引用和相等\n",
    "在 Python 中有两种不同的方法去检查是否相等:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L = [1, 2, 3]\n",
    "M = L                   # 创建共享引用\n",
    "L == M                  # 值相等"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L is M                  # 相同对象"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "“== 操作符”,测试两个被引用的对象是否具有相同的值。  \n",
    "\n",
    "“is 操作符”,检查对象的同一性,是否精确地指向同一个对象。可以是检测共享引用的一种办法。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L = [1, 2, 3]\n",
    "M = [1, 2, 3]\n",
    "L == M"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L is M                  # 不同的对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X = 42\n",
    "Y = 42\n",
    "X == Y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X is Y"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "因为小的整数和字符串被缓存并复用,所以 X 和 Y 引用了一个相同的对象。"
   ]
  },
  {
   "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.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值