Python 个人学习记录

2019-12-09 1537点热度 2人点赞

Python 个人学习记录 python v3.8+


0 、理念

程序代码的运行流程:输入、处理、输出

IPO 模式的问题描述:问题、问题理解、建立模型、构思算法、编程实现、程序运行

计算机问题求解的步骤:IPO 描述、算法(流程图)、程式代码

撰写 条件判断/循环结构 时,先写框架,先用 占位语句 填充,保证循环体完整。

>>> import this
The Zen of Python, by Tim Peters

 Beautiful is better than ugly.    优美优于丑陋
 Explicit is better than implicit.    明了优于隐晦
 Simple is better than complex.    简单优于复杂
 Complex is better than complicated.    复杂优于凌乱
 Flat is better than nested.    扁平优于嵌套
 Sparse is better than dense.    稀疏优于稠密
 Readability counts.    可读性很重要
 Special cases aren't special enough to break the rules.    即使实用比洁癖更优。
 Although practicality beats purity.    所谓的"特例"也往往没有特殊到必须违背上述规则的程度
 Errors should never pass silently.    错误绝不能悄悄忽略
 Unless explicitly silenced.    除非它明确需要如此
 In the face of ambiguity, refuse the temptation to guess.    面对不确定性,拒绝妄加猜测
 There should be one-- and preferably only one --obvious way to do it.    任何问题应有一种,且最好只有一种,一目了然的途径
 Although that way may not be obvious at first unless you're Dutch.    当然这是没法一蹴而就的,除非你是荷兰人
 Now is better than never.    立刻着手 好过 永远不做
 Although never is often better than right now.    永远不做 好过 闷头蛮干
 If the implementation is hard to explain, it's a bad idea.    倘若你的实现很难解释,必然是坏方法。
 If the implementation is easy to explain, it may be a good idea.    倘若你的实现很好解释,可能是好方法。
 Namespaces are one honking great idea -- let's do more of those!    命名空间是个绝妙的主意,我们应好好利用它

1 、词法

1.1 、基础

文档链接 [ 链接 ]
运算符优先级 [ 链接 ]
标准函数 [ 链接 ]
术语对照表 [ 链接 ]
表达式 [ 链接 ]


1.2 、格式

# -*- coding: utf8 -*- 声明源码文件的编码格式,默认 UTF8
# 单行注释
\ 结尾表示显示行拼接(逻辑行)不支持注释
: 结尾表示下方为一个模组,需要使用缩进。
全部代码对于三种字符命令不支持 $ ? ` 发现会直接报错
Python 语言建议采用 PEP8 的代码格式设置指南,其中约定俗成的单行代码长度建议为 80 字符。
Python 语言采用严格的 “缩进” 来表明程序的格式框架,用以在 Python 中标明代码的层次关系。
1 个缩进= 4 个空格= Tab 键,两者不可混用

用空行分隔函数和类,及函数内较大的代码块。
最好把注释放到单独一行。
使用文档字符串(__doc__)。
运算符前后、逗号后要用空格,但不要直接在括号内使用: a = f(1, 2) + g(3, 4)。
类和函数的命名要一致;按惯例,命名类用 UpperCamelCase(大驼峰拼写法,所有单词首字母大写),命名函数与方法用 小写与下划线混合 。
类的命名方法中第一个参数总是用 self 。
编写用于国际多语环境的代码时,不要用生僻的编码。 Python 默认的 UTF-8 或纯 ASCII 可以胜任各种情况。同理,就算多语阅读、维护代码的可能再小,也不要在标识符中使用非 ASCII 字符。
' 单引号内容可以做字符串注释 '
" 双引号内容可以做字符串注释 "
'''
    三引号内容可以
    跨行做字符串注释
'''
"""
    三引号内容可以
    跨行做字符串注释
"""

格式迷你语言 [ 链接 ] [ 链接 ]

.format(value[, format_spec])
'{:02}d {:02}:{:02}:{:02}'.format(time//86400, time%86400//3600, time%3600// 60, time%60)

1.3 、变量

变量 保存和表示具体的数据值(和其他信息)
  • 变量赋值时同时获得数据的类型和数据值
  • Python 是动态的强类型语言
  • 不需要显式声明类型,根据值确定类型
  • 通过 “引用” 把变量和值(对象)连接起来
 标识符:用户定义的名称
  • 用户定义的变量名、常量名和函数名等都是标识符
  • 命名规则:
  • 标识符由大写字母、小写字母、数字、下划线 (_) 和汉
  字等字符组合而成
  • 首字符不能是数字
  • 标识符不能包含空格,长度没有限制
  • 区分大小写,python 和 Python 是两个不同的名字
  • 建议使用有意义、易区分的标识符
 关键字:也称为保留字,指被编程语言内部定义并保留
  使用的标识符
  • 不建议把关键字作为标识符重新定义,这样会覆
  盖其原有的定义
  • 通过语法高亮可以区分出关键字,可以在标识符
  的后面加上一个下划线来与关键字区分
 标识符要见名识义
  • 双下划线开头并结束的标识符是系统使用的,程序中应避免使用
  • 双下划线开头但非下划线结束的标识符通常表示私有量
  • 单下划线开头的标识符表示保护量

类型推荐命名规则举例
  模块/包名,全小写字母,简单有意义,如需要可使用下划线,math 、 sys
  函数名,全小写字母,可使用下划线增加可读性,foo() 、 my_func()
  变量名,全小写字母,可使用下划线增加可读性,age, my_var
  类名,采用 PascalCase 命名规则,即可多个单词组成名称,每个单词除第一个字符大写外,其余的字母均小写,MyClass
  常量名,全大写字母,可使用下划线增加可读性 LEFT,TAX_RATE
一个对象的哈希值如果在其生命周期内绝不改变,就被称为 可哈希 ,并可以同其他对象进行比较。可哈希对象必须具有相同的哈希值比较结果才会相同。
大多数 Python 中的不可变内置对象都是可哈希的;可变容器(例如 list 列表或字典)都不可哈希;不可变容器(例如 tup 元组和 frozenset 不可变集合)仅当它们的元素均为可哈希时才是可哈希的。 用户定义类的实例对象默认是可哈希的。 它们在比较时一定不相同(除非是与自己比较),它们的哈希值的生成是基于它们的 id() 。
a,b = b,a 变量对调赋值 (指针)

1.5 、算数运算

相同运算符,从后往前计算

4**3**2 == 4**9 == 262144
2**2**2**2 == 2**2**4== 2**16 == 65535

+ 加
- 减
* 乘
/ 商
// 整除商
% 余数 3 % 2 == 1
** 乘方 0 ** 0 == 1 
pow(x,y) 乘方 x 的 y 次幂(等同**)(pow(4,1/2) 为开平方根)
abs(x) 绝对值
divmod(x,y) 整除和余数
-x 取反
+x 不变
sum(iterable,start=0) 列表求和
虽然 abs(x%y) < abs(y) 在数学中必为真,但对于浮点数而言,由于舍入的存在,其在数值上未必为真。 例如,假设在某个平台上的 Python 浮点数为一个 IEEE 754 双精度数值,为了使 -1e-100 % 1e100 具有与 1e100 相同的正负性,计算结果将是 -1e-100 + 1e100,这在数值上正好等于 1e100 。 函数 math.fmod() 返回的结果则会具有与第一个参数相同的正负性,因此在这种情况下将返回 -1e-100 。 何种方式更适宜取决于具体的应用。
如果 x 恰好非常接近于 y 的整数倍,则由于舍入的存在 x//y 可能会比 (x-x%y)//y 大。 在这种情况下,Python 会返回后一个结果,以便保持令 divmod(x,y)[0] * y + x % y 尽量接近 x.
&按位与
| 按位或
^ 按位异或
~ 按位取反 (等于 -x-1)
<< 按位左移,高弃低补 0
>> 按位右移,低弃高补 0

1.6 、命令

使用指定解释器运行 pip 更新

/usr/bin/python3 -m pip install --upgrade pip

(Windows 因 pip.exe 占用无法更新时必须使用该方式运行 python.exe


2 、数据格式类型篇

文档链接 [ 链接 ]

id(x) 查询引用内存地址 (指针)
type(x) 返回 x 的类型
isinstance(x,int) 检查 x 的类型是否为 int
hex(x) 把整数 x 的值转换成 16 进制表示
bin(6) == '0b111'
bin(6)[2:] == '111' 转换十进制为二进制 str
int('',2) 转换 2 进制 的 str 为十进制数值
创建 元组 (),列表 [],字典 {}(实际显示情况是集合 {} 字典 {:})

2.1 、空值 None

此类型只有一种取值。是一个具有此值的单独对象。此对象通过内置名称 None 访问。在许多情况下它被用来表示空值,例如未显式指明返回值的函数将返回 None 。它的逻辑值为假。


2.2 、数值 numbers.Number

此类对象由数字字面值创建,并会被作为算术运算符和算术内置函数的返回结果。数字对象是不可变的;一旦创建其值就不再改变。 Python 中的数字当然非常类似数学中的数字,但也受限于计算机中的数字表示方法。


2.2.1 、整数

整数型 (int)

此类对象表示任意大小的数字,仅受限于可用的内存 (包括虚拟内存) 。在变换和掩码运算中会以二进制表示,负数会以 2 的补码表示,看起来像是符号位向左延伸补满空位。

可转换的原数据类型 float() str() bytes()
双精度浮点数转换时进行整数部截断,参阅 math.floor() 和 math.ceil()
int(float(x.y)) == x
int(1.23) == 1
int(-4.56) == -4
str() 与 bytes() 转换时,原数据仅允许 数字 和 + - 存在。

布尔型 (bool)

此类对象表示逻辑值 False 和 True 。代表 False 和 True 值的两个对象是唯二的布尔对象。布尔类型是整型的子类型,两个布尔值在各种场合的行为分别类似于数值 0 和 1,例外情况只有在转换为字符串时分别返回字符串 "False" 或 "True"。

逻辑值检测 [ 链接 ]

常见的 bool(x) == False 判定
被定义为假值的常量: None 和 False 。
任何数值类型的零: 0, 0.0, 0j, Decimal(0), Fraction(0, 1)
空的序列和多项集: '', (), [], {}, set(), range(0)

对于 class 类 而言,还可以通过声明 __bool__ 并 自定义布尔值 [ 链接 ]

>>> class Account:
	def __init__(self, balance):
		self.balance = balance
		
	def __bool__(self):
		return self.balance > 0

>>> account1 = Account(500)
>>> bool(account1)
True
>>> account2 = Account(0)
>>> bool(account2)
False

2.2.2 、双精度浮点数 (float)

此类对象表示机器级的双精度浮点数。其所接受的取值范围和溢出处理将受制于底层的机器架构 (以及 C 或 Java 实现) 。 Python 不支持单精度浮点数;支持后者通常的理由是节省处理器和内存消耗,但这点节省相对于在 Python 中使用对象的开销来说太过微不足道,因此没有理由包含两种浮点数而令该语言变得复杂。

可转换的原数据类型 int() str() bytes()
整数转换时补一位小数.0
float(int(x)) == x.0
str() 转换时,原数据仅允许 数字 和 + - . 存在。(特例是 "nan" "inf"分别表示非数字 NaN 以及 无穷)
bytes() 转换时,原数据仅允许 数字 和 + - . 存在。
float.is_integer() 检查 浮点数 是否可以写为 为 int
float%1==0 检查 浮点数 是否存在小数

注意浮点数在计算时可能出现的 误差 问题

>>> 1.0+2.0-3.0
0.0
>>> 0.1+0.2-0.3
5.551115123125783e-17

2.2.3 、双精度浮点数+复数 (complex)

此类对象以一对机器级的双精度浮点数来表示复数值。有关浮点数的附带规则对其同样有效。一个复数值 z 的实部和虚部可通过只读属性 z.real 和 z.imag 来获取。

可转换的原数据类型 int() float() str()
整数和浮点数转换时补一份虚数 0j
complex(int(x)) == x+0j
字符串先转换为整数和浮点数然后再转换为虚数。
(a+bj).real == a
(a+bj).imag == b

2.2.3 、 decimal 类

decimal 模块支持十进制浮点运算的正确和科学计数法。 [ 链接 ]

>>> import decimal
>>> getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[Inexact, Rounded], traps=[InvalidOperation, DivisionByZero, Overflow])

>>> decimal.Decimal(1)/7
Decimal('0.1428571428571428571428571429')

>>> getcontext().prec = 5

>>> decimal.Decimal(1)/7
Decimal('0.14286')

2.3 、不可变序列类型

不可变序列类型的对象一旦创建就不能再改变。 (如果对象包含对其他对象的引用,其中的可变对象就是可以改变的;但是,一个不可变对象所直接引用的对象集是不能改变的。)

len() 获取序列长度
max() 获取序列最大元素(需可比较)
min() 获取序列最小元素(需可比较)
sorted() 对序列进行 按首字母升序排序 但不将排序写入到该列表,使用参数'reverse=True'变成降序
eval() 将字符串当作有效表达式并重新输出(可以转换错误的数据格式)
enumerate(序列,start=0) 读取 List 并搭配序列计数值到 新的二元元组 中,默认计数从 0 开始以 1 自增,形成二元元组结构为 ((0, 序列 S1),(1, 序列 S2))
s + t 产生连接 s 和 t 后的序列
s * n 产生序列 s 复制 n 次后的序列(n * s 同样)

2.3.1 、字符串 str()

字符串是由 Unicode 码位值组成的序列。范围在 U+0000 - U+10FFFF 之内的所有码位值都可在字符串中使用。 Python 没有 char 类型;而是将字符串中的每个码位表示为一个长度为 1 的字符串对象。内置函数 ord() 可将一个码位由字符串形式转换成一个范围在 0 - 10FFFF 之内的整型数;chr() 可将一个范围在 0 - 10FFFF 之内的整型数转换为长度为 1 的对应字符串对象。 str.encode() 可以使用指定的文本编码将 str 转换为 bytes,而 bytes.decode() 则可以实现反向的解码。

str[1:4] 字符串切片(参考列表切片)
str.encode(encoding="utf-8")  将字符串编码转换为其他编码
str.title() 首字母大写
str.upper() 全大写
str.lower() 全小写 常用方法为自动 lower 过滤字符大小写,需要的时候再整形。
str.casefold() 全小写,但会额外涉及到各国语言字符的强制英文小写的表达形式。
str.expandtabs(tabsize=8)  去除制表符 Tab 并指定制表宽度为 tabsize 个空格

str.removeprefix('')  匹配后对字符串的 前缀 进行去除,如未匹配到则返回原字符串内容
str.removesuffix('')  匹配后对字符串的 后缀 进行去除,如未匹配到则返回原字符串内容
str.lstrip()        去除 开头 空白和换行符,但不写入原数据。
str.rstrip()        去除 末尾 空白和换行符,但不写入原数据。
str.strip()         去除 两端 空白和换行符,但不写入原数据。
str.split()      按 分割字符 切割字符串为新的 list() ,从左往右,可指定分割字符,分割次数例如 maxsplit=1
str.rsplit()     按 分割字符 切割字符串为新的 list() ,从右往左,可指定分割字符,分割次数例如 maxsplit=1
str.splitlines() 按 行边界 切割字符串为新的 list() ,可手动指定行边界
str.rpartition() 按 分隔字符 切割字符串为 三个 元组 (分隔符前, 分隔字符, 分隔符后) 。如无分隔符 ('','','str')

str.zfill(width)       对字符对齐填充到 int(width) 长度的字符, 左侧 填充字符为 '0' ,如存在负号占用一位。
str.rjust(width,' ')   对字符对齐填充到 int(width) 长度的字符, 左侧 填充字符默认为 ' '(空格) 。
str.ljust(width,' ')   对字符对齐填充到 int(width) 长度的字符, 右侧 填充字符默认为 ' '(空格) 。
str.center(width,' ')  对字符对齐填充到 int(width) 长度的字符, 中侧 填充字符默认为 ' '(空格) 。

.find('one',i,j) 在字符串中从 i 到 j 中查找第一个满足条件的指定字符串所在位置,否则返回 -1
.count('one') 在字符串中查找符合指定的 one 的字符串的个数,匹配的方式为 list ,可以额外对匹配的 list 切片
.replace(old,new,count) 在字符串中将 old 替换为 new ,替换次数为 count(可省略为替换全部)

str.encode(encoding="utf-8", errors="strict")

.translate 新版本使用说明 [ 链接 ]
.translate(str.maketrans('AX', 'BY', 'CZ'))  对单字符串进行对等替换,将 A 码改为 B 码,将 X 码改为 Y 码,将 C 码和 Z 码删除。
.translate(str.maketrans({'A': 66 }))  对单字符串依 ascii 码非对等替换, 将字符'A'替换为字符'B'。 ( B = ascii 66; )
.translate(str.maketrans({'A': '\u4f60\u597d' })) 对单字符串依 unicode 码非对等替换, 将字符'A'替换为字符'你好'。 ( a = unicode &#97; )

.isalpha() 满足字母条件
.isdigit() 满足数字条件(十进制数字)
.isnumeric() 数字和数学字符 ⅕ Ⅷ
.isalnum() 满足字母+数字条件
.isascii() 符合 ASCII 字符类型(包含空格和空字符串)
.isupper() 判断字母全大写
.islower() 判断字母全小写
.isidentifier() 判断满足标识符条件
.isprintable() 判断不存在转义字符
.isspace() 判断空格
.startswith(tuple,i,j) 判断是否前缀等同,查询项为 str/tuple 格式,查找源字符串截取位置 str[i:j]
.endswith(list,) 判断是否后缀等同,查询项为 str/tuple 格式,查找源字符串截取位置 str[i:j]

2.3.2 、元组 tuple()

一个元组中的条目可以是任意 Python 对象。包含两个或以上条目的元组由逗号分隔的表达式构成。只有一个条目的元组 ('单项元组') 可通过在表达式后加一个逗号来构成 (一个表达式本身不能创建为元组,因为圆括号要用来设置表达式分组) 。一个空元组可通过一对内容为空的圆括号创建。

tup = ( 'one', 'two', 'three', 'four' )

读取方式(负数从后调用)
tup[:] 获取元组所有元素 == ( 'one', 'two', 'three', 'four' )
tup[0] 获取元组首元素 == one(不存在 -0 的概念)
tup[-1] 获取元组尾元素 == four
tup[1:3] 获取元组指定元素段 1<= x <3 == ( 'two', 'three')
tup[-4:-1] 获取元组指定元素段 0<= x <3 == ( 'one', 'two', 'three')
tup[1:4:2] 获取元组指定元素段 1<= x <4 步进为 2 == ( 'one', 'three')
for i in tup: 遍历元组所有元素

元组不可被编辑
del tup 删除整个元组

2.3.3 、字节串 bytes()

字节串对象是不可变的数组。其中每个条目都是一个 8 位字节,以取值范围 0 <= x < 256 的整型数表示。字节串字面值 (例如 b'abc') 和内置的 bytes() 构造器可被用来创建字节串对象。字节串对象还可以通过 decode() 方法解码为字符串。


2.4 、可变序列类型

可变序列在被创建后仍可被改变。下标和切片标注可被用作赋值和 del (删除) 语句的目标。


2.4.1 、列表 list()

列表中的条目可以是任意 Python 对象。列表由用方括号括起并由逗号分隔的多个表达式构成。 (注意创建长度为 0 或 1 的列表无需使用特殊规则。)
列表支持多层列表互相嵌套

list = [ 'one', 'two', 'three', 'four' ]
list_a = list[:] 和 list_a = list 效果不同,前者创建新的内存空间,后者为指针。
list( range(2, 14, 3) ) =  [2, 5, 8, 11]
range(a,b,x) 创建一个列表,最小是 a(省略默认 0) ,最大是 b ,步进是 x(省略默认 1,不可以等于 b)
[*range(5)] 快速创建一个数值列表,结果为 [0, 1, 2, 3, 4] 

读取方式(负数从后调用)
list[:] 获取列表所有元素 == [ 'one', 'two', 'three', 'four' ]
list[0] 获取列表首元素 == one(不存在 -0 的概念)
list[-1] 获取列表尾元素 == four
list[1:3] 获取列表指定元素段 1<= x <3 == [ 'two', 'three']
list[-4:-1] 获取列表指定元素段 0<= x <3 == [ 'one', 'two', 'three']
list[1:4:2] 获取列表指定元素段 1<= x <4 步进为 2 == [ 'one', 'three']
.index('one',i,j) 在列表中从 i 到 j 中查找第一个满足条件的元素所在位置,找不到报错 ValueError

修改方式
.append('five') 在列表中追加一个元素(插入在列表最后的位置)
.insert(0, 'six') 在列表中的目标位置插入一个元素(插入点元素顺次右移)
del list[0] 在列表中完全删除一个元素(删除点元素顺次左移)并不再使用
.pop(0) 在列表中的目标位置弹出一个元素(弹出点元素顺次左移)并可以直接赋值使用(默认最后一个元素)
.remove('one') 在列表中查找第一个满足条件的元素将其删除(删除点元素顺次左移)并可以直接赋值使用
.extend(listnew) 在列表后追加新列表中的所有元素
.copy(listnew) 复制列表数据到新的列表中(深拷贝)(修改影响自身)
list1 = list2 将 list1 的内存指向到 list2 上(浅拷贝)(修改影响两个)
.count('one') 在字符串中查找符合指定的 one 的字符串的个数,匹配的方式为 list ,可以额外对匹配的 list 切片

排序方式
.sort() 对列表进行 按首字母升序排序 并将排序写入到该列表,使用参数'reverse=True'变成降序
sorted(iterable,*,key=,reverse=) 使用 key 对 列表内所有元素迭代,并参考迭代结果进行排序,多排序关键词可以用元组 (x,y) 实现
sorted() 对序列进行 按首字母升序排序 但不将排序写入到该列表,使用参数'reverse=True'变成降序
.reverse() 对列表进行 反转排序 并将排序写入到该列表

转换方式
"?".join(list) 将数组转换为字符串,并以 ? 为分隔符

2.4.2 、字节数组

字节数组对象属于可变数组。可以通过内置的 bytearray() 构造器来创建。除了是可变的 (因而也是不可哈希的),在其他方面字节数组提供的接口和功能都与不可变的 bytes 对象一致。


2.5 、集合

集合表示由不重复不可变对象组成的无序且有限的集合。因此它们不能通过下标来索引。但是它们可被迭代,也可用内置函数 len() 返回集合中的条目数。集合常见的用处是快速成员检测,去除序列中的重复项,以及进行交、并、差和对称差等数学运算。

对于集合元素所采用的不可变规则与字典的键相同。注意数字类型遵循正常的数字比较规则: 如果两个数字相等 (例如 11.0),则同一集合中只能包含其中一个。

set(list) 创建可变集合,可以用 add() 增加集合元素
frozenset() 创建不可变集合

集合的使用 [ 链接 ]

dataScientist = set(['Python', 'R', 'SQL', 'Git', 'Tableau', 'SAS'])
dataEngineer = set(['Python', 'Java', 'Scala', 'Git', 'SQL', 'Hadoop'])

# 全集
dataScientist.union(dataEngineer)
dataScientist | dataEngineer

# 交集
dataScientist.intersection(dataEngineer)
dataScientist & dataEngineer

# 排除集合
dataScientist.difference(dataEngineer)
dataScientist - dataEngineer

# 反并集
dataScientist.symmetric_difference(dataEngineer)
dataScientist ^ dataEngineer

# 子集检测
mySkills.issubset(possibleSkills)

2.6 、映射

映射对象表示由任意索引集合所索引的对象的集合。通过下标 a[k] 可在映射 a 中选择索引为 k 的条目;这可以在表达式中使用,也可作为赋值或 del 语句的目标。内置函数 len() 可返回一个映射中的条目数。

2.6.1 、字典

字典表示由几乎任意值作为索引的有限个对象的集合。不可作为键的值类型只有包含列表或字典或其他可变类型,通过值而非对象编号进行比较的值,其原因在于高效的字典实现需要使用键的哈希值以保持一致性。
用作键的数字类型遵循正常的数字比较规则: 如果两个数字相等 (例如 11.0) 则它们均可来用来索引同一个字典条目。

字典会保留插入顺序,这意味着键将以它们被添加的顺序在字典中依次产生。 替换某个现有的键不会改变其顺序,但是移除某个键再重新插入则会将其添加到末尾而不会保留其原有位置。

字典本身是可变的;它们可通过 {...} 标注来创建,字典的条目是可变的,字典的索引是不可变的。

dict = {'type': 'dicttype'}
dict['type'] 获取 dict 字典索引为 type 的条目内容 == dicttype
dict['color'] = 'red' 赋予 dict 字典索引为 color 的键值为 red == {'type': 'dict', 'color': 'red'}
dict['color'] = 'blue' 赋予 dict 字典索引为 color 的键值覆盖为 blue == {'type': 'dict', 'color': 'blue}
del dict['color'] 删除 dict 字典索引为 color 的键值对
dict.items()      查看字典所有键值(随机顺序)
dict.keys()       查看字典所有键名(随机顺序)
list(dict.keys()) 查看字典所有键名并输出为列表
dict.values()     查看字典所有数值(随机顺序)
for key,value in dict.items(): 遍历字典所有键值
list(mydisc.keys())[list(mydisc.values()).index(get_value)] 根据数值反查第一个键名
# 常见的字数统计
for i in dice:
    dict[i]=dice.count(i)

3 、输入,输出,储存篇

3.1 、输入输出

print('str1' 'str2')
str1str2
print('str1' * 3 + 'str2')
str1str1str1str2
print('str1','str2',sep=' ',end='**\n')
str1 str2**
local1, local2 ='str1', 'str2'       
print("Hello#?{} is str1, {} is str2".format(local1,local2))
Hello#?str1 is str1, str2 is str2
print(r'C:\some\name')
C:\some\name
input() 等待用户输入字符串文本
input("Wait input") 带提醒的等待输入
dict()
set()
hex()

3.2 、文件的调用

3.2.1 、文本文件的调用

[ 链接 ]

对于 文本文件的处理,主要使用的是三个函数

f = open('workfile.txt', mode='r', encoding='')
read_str = f.read()
f.close()
f = open('workfile.txt', mode='w', encoding='gbk')
f.write('Write Str Something')
f.close()
# 将文件内容读取并转换为 str 储存
with open('workfile.txt', mode='r', encoding='gbk') as f:
    read_str = f.read()
# 将文件内容按行转换为 List 储存(不含换行符)
with open('workfile.txt', mode='r', encoding='gbk') as f:
     read_list = list(f)


3.2.2 、 Json 文件的调用

从文件写入或读取字符串很简单,数字则稍显麻烦,因为 read() 方法只返回字符串,这些字符串必须传递给 int() 这样的函数,接受 '123' 这样的字符串,并返回数字值 123 。保存嵌套列表、字典等复杂数据类型时,手动解析和序列化的操作非常复杂。

Python 支持 JSON (JavaScript Object Notation) 这种流行数据交换格式,用户无需没完没了地编写、调试代码,才能把复杂的数据类型保存到文件。 json 标准模块采用 Python 数据层次结构,并将之转换为字符串表示形式;这个过程称为 serializing(序列化)。从字符串表示中重建数据称为 deserializing(解序化)。在序列化和解序化之间,表示对象的字符串可能已经存储在文件或数据中,或通过网络连接发送到远方 的机器。

关于更多内容可以参考 Python [ 链接 ]

json.dumps(source_date)
json.loads(source_date)
json.dump(source_date, f)
json.load(f)

3.2.3 、 CSV 文件的调用


4 、条件逻辑错误处理篇

4.1 、程序控制结构

常见的程序控制结构 顺序结构/循环结构/分支结构

IF 条件判断与分支结构(双分支,多分支
主要分为条件表达式+语句块,条件表达式包括 关系表达式 和 逻辑表达式
if 条件表达式 1:
  语句块 A
elif 条件表达式 2:
  语句块 B
else:
  语句块 C
For 多用于固定可控次数的循环结构
循环控制变量 会自动变化,不建议在语句块中修改 循环控制变量 和 序列
如 for _ in range(1,5): 操作循环体执行 4 次执行,同时循环控制变量
for 循环控制变量:
    循环体
一行版本的 IF 表达式格式
表达式 A if 条件 else 表达式 B
print('yes') if bool(1) else print('no')
if 条件:
  表达式 A
else:
  表达式 B
While 多用于未知次数的循环结构
while 条件表达式 1:
  语句块
pass 占位语句
container 语句立刻结束其所在循环的本轮循环,准备进入下一轮循环
break 立刻结束 while 其所在的最里层循环并跳出
[生成器] 一行版本的 FOR 表达式格式(comprehension 生成器格式,转换输出 List)
[可迭代对象表达式 for 代码块 A for 代码块 B]
[str(x)+str(y) for x in range(3) for y in range(3)]
for 代码块 A:
  for 代码块 B:
    可迭代对象表达式
[生成器] 一行版本的 IF FOR 混合多层嵌套表达式格式(comprehension 生成器格式,转换输出 List)
[循环体 for 代码块 A if 条件 B for 代码块 C if 条件 D ]

for 代码块 A:
  if 条件 B:
    for 代码块 C:
      if 条件 D:
        可迭代对象表达式

[str(x)+str(y) for x in range(4) if x > 1 for y in range(4) if x*y > 0]

templist=[]
for x in range(4):
  if x > 1:
    for y in range(4):
      if x*y > 0:
        templist.append(str(x)+str(y))
print(templist)

['21', '22', '23', '31', '32', '33']

# 九九乘法表
[str(x)+"*"+str(y) for x in range(1,10) for y in range(1,x+1)]

4.2 、关系表达式 与 逻辑表达式

关系表达式 用 逻辑运算符 连接起来构成 逻辑表达式

运算符优先级 [ 链接 ]

常见规则优先级 非 not > 与 and > 或 or
关系 x is s : 判断 x 是否与 s 的主体是否相同 (内存地址)
关系 x in s : 判断 x 是否为 s 中的元素
关系 x == s : 判断 x 是否与 s 的相同数值 
== 数据相同
!= 数据不同
> 大于
>= 大于等于
< 小于
<= 小于等于
in 在数组中
not in 不在数组中
is 主体同属

关于 -5 到 256 的整数,在 Python 中会被优化储存,共用一组内存。对这个范围的变量时,关系运算符 is 和 == 产生相同结果。在使用 is 对比时有同样情况的还有 不可变序列类型 比如 元组


4.3 、异常处理

try 语句 [ 链接 ]

异常 [ 链接 ]

下例会要求用户一直输入内容,直到输入有效的整数,但允许用户中断程序(使用 Control-C 或操作系统支持的其他操作);注意,用户中断程序会触发 KeyboardInterrupt 异常。

while True: 
    try:
        x = int(input("Please enter a number: "))
        break
    except ValueError:
        print("Oops!  That was no valid number.  Try again...")

try 语句的工作原理如下:

  • 首先,执行 try 子句tryexcept 关键字之间的 多行 语句)。
  • 如果没有触发异常,则跳过 except 子句try 语句执行完毕。
  • 如果执行 try 子句时发生了异常,则先行跳过该子句中剩下的部分。如果异常的类型与 except 关键字后面的异常匹配,则执行 except 子句,然后,再继续执行 try 语句之后的代码。
  • 如果发生的异常不是 except 子句中列示的异常,则将其传递到外部的 try 语句中;如果没有找到处理程序,则它是一个 未处理异常,语句执行将终止,并显示如上所示的消息。

try 语句可以有多个 except 子句,可为不同异常指定相应的处理程序。但最多只会执行一个处理程序。处理程序只处理对应的 try 子句中发生的异常,而不处理同一 try 语句内其他处理程序中的异常。 except 子句可以用元组命名多个异常,例如:

函数体的 try 语句体系内出现错误时 执行额外内容
def f():
     try:
         print('try')
     finally:
         print('finally')
函数体的 错误处理(含错误结束清理)
def f():
try:
print('try')
except Exception as Error:
try:
print('error_info')
finally:
del Error

5 、函数,类篇

Python 编写函数时,需要牢记几个细节。

应给函数指定描述性名称,且只在其中使用小写字母和下划线。描述性名称可帮助你和别人明白代码想要做什么。给模块命名时也应遵循上述约定。

每个函数都应包含简要地阐述其功能的注释,该注释应紧跟在函数定义后面,并采用文档字符串格式(多行三引号形式)。文档良好的函数让其他程序员只需阅读文档字符串中的描述就能够使用它:他们完全可以相信代码如描述的那样运行;只要知道函数的名称、需要的实参以及返回值的类型,就能在自己的程序中使用它。

给形参指定默认值时,等号两边不要有空格, 对于函数调用中的关键字实参,也应遵循这种约定。如果形参很多,导致函数定义的长度超过了 79 字符,可在函数定义中输入左括号后按回车键,并在下一行按两次 Tab 键,从而将形参列表和只缩进一层的函数体区分开来。

如果程序或模块包含多个函数,可使用两个空行将相邻的函数分开,这样将更容易知道前一个函数在什么地方结束,下一个函数从什么地方开始。

所有的 import 语句都应放在文件开头,唯一例外的情形是,在文件开头使用了注释来描述整个程序。


5.1 、函数的创建与使用

创建一个函数 describe_per 并准备两个形参,其中第二个形参的默认值为 'dog' 
函数返回值为最后一个 return 即 person (无 return 时返回 None)
def describe_per(pet_name, animal_type='dog'):
    person=str("I have a " + animal_type +  ". " + "My " + animal_type + "'s name is " + pet_name.title() + ".")
    return person
含默认值的形参定义必须在靠后的位置,避免出现形参-实参对应问题。

函数支持的同结果调用方式如下(位置参数,关键字参数,默认是 位置/关键字参数,其他方式参考 [  ])
describe_per('willie') #省略第二参数
describe_per('willie', 'dog')
describe_per(animal_type='dog', pet_name='willie') #支持
describe_per(pet_name='willie', animal_type='dog')

describe_per('harry', 'hamster')
describe_per(animal_type='hamster', pet_name='harry')
describe_per(pet_name='harry', animal_type='hamster')
可以通过传入列表的方式多次处理(使用 for),同时传入列表可以是列表副本 list[:] 但会增加内存占用
def describe_per(pet_names, animal_type='dog'):
    for pet_name in pet_names:
        print("I have a " + animal_type +  ". " + "My " + animal_type + "'s name is " + pet_name.title() + ".")

describe_per(['cat1','cat2','cat3'],'cat')
type(pet_names) = <class 'list'>
可以通过 *形参 的方式传递多个实参,传入的多个实参会转换为 元组 处理。(注意形参声明顺序)
def describe_per(*pet_names, animal_type):
    for pet_name in pet_names:
        print("I have a " + animal_type +  ". " + "My " + animal_type + "'s name is " + pet_name.title() + ".")

describe_per('cat1','cat2','cat3',animal_type='cat')
可以通过 **形参 的方式传递多组数据,传入的多个实参会转换为 字典 处理。(可以和 *形参 一起使用)
def build_profile(name, **user_info):
    profile = {}
    profile['name'] = name
    for key, value in user_info.items():
        profile[key] = value
    return profile

build_profile('lilei',location='princeton',field='physics')
注意默认值声明在联动变量时,默认只计算一次。 [ 链接 ]
当默认值为列表、字典或类实例等可变对象时,会产生与该规则不同的结果,所以为了避免需要使用 None 并进行判断
def f(a, L=[]):
     L.append(a)
     return L
print(f(1))
[1]
print(f(2))
[1, 2]
print(f(3))
[1, 2, 3]

5.2 、函数的相互调用

关于 import [ 链接 ]

import math 从 数学 模块 (math.py) 中 导入 所有 函数
math.pow() 调用方式

from math import pow, fabs 从 数学 模块 (math.py) 中 仅导入 pow 函数 (def pow)
pow() 调用方式
fabs() 调用方式

from math import pow as ppooww 从 数学 模块 (math.py) 中 仅导入 pow 函数 (def pow),并指定函数别名为 ppooww
ppooww() 调用方式
常用的 time 库 及其调用参考
import time 加载 time 库(时间相关)
time.time() 输出 UNIX 时间,秒为单位 (float)
time.time_ns() 输出 UNIX 时间,纳秒为单位 (int)
time.perf_counter() 输出本地性能计数器时间,秒为单位 (float),相比上方精度更高
time.perf_counter_ns() 输出本地性能计数器时间,纳秒为单位 (int),相比上方精度更高
time.process_time() 输出线程运行时间,秒为单位 (float),不包含 sleep 的线程休眠时间
time.process_time_ns() 输出线程运行时间,纳秒为单位 (int),不包含 sleep 的线程休眠时间
lambda 函数 用法 [ 链接 ]

lambda x , y : x + y
等价于
def lambdatemp(x,y):
     return x+y

lambda :None 无输出函数
sleep=lambda x:None 将一个单输入函数 sleep 配置为无输出(禁用该函数)
filter 函数
filter(函数, 序列)  对单个序列中的每个元素都分别输入函数一次并将 函数执行结果为 True 的 元素 按顺序储存在 Iterable 数据流 (filter object) 中
filter(function, iterable) == (item for item in iterable if function(item))
filter(None, iterable) == (item for item in iterable if item)
filterfalse(function, iterable) == (item for item in iterable if not function(item))
map 函数
map(函数, 序列) 将单个序列中的每个元素都分别输入函数一次并将 函数执行结果 按顺序储存在 Iterable 数据流中,该数据流只能使用一次,可通过转换格式为需要的序列如 list(map()) 查看
map(function, iterable) == (bool(function(item)) for item in iterable )
starmap(function, iterable) == (bool(function(item)) for item in iterable )
>>> [range(item) for item in range(10) if len(range(item))%2==0]
[range(0, 0), range(0, 2), range(0, 4), range(0, 6), range(0, 8)]

>>> list( item for item in range(10) if len(range(item))%2==0 )
[0, 2, 4, 6, 8]
>>> list( filter( lambda item : len(range(item))%2==0 , range(10) ) )
[0, 2, 4, 6, 8]
>>> from itertools import filterfalse
>>> list( filterfalse( lambda item : len(range(item))%2==0 , range(10) ) )
[1, 3, 5, 7, 9]

>>> list( bool( len(range(item))%2==0 ) for item in range(10) )
[True, False, True, False, True, False, True, False, True, False]
>>> list( map( lambda item : len(range(item))%2==0 , range(10) ) )
[True, False, True, False, True, False, True, False, True, False]
>>> from itertools import starmap
>>> list( starmap( pow, [(2,5), (3,2), (10,3)] ) )
[32, 9, 1000]
reduce 函数

5.3 、类的创建与引用


5.4 、迭代器 与 可迭代对象

可迭代对象 iterable
能够 next() 一次 返回一个成员 的 对象。 iterables 的实例包括所有类型的序列(如 list,str,和 tuple)和一些非序列类型(如 dict, file object)和自定义类中声明过 __iter__() 的方式 或 声明过 __getitem__() 以满足 序列 sequence 语义 的方式。

>>> list(range(5))
[0, 1, 2, 3, 4]

迭代器

>>> dd=iter(range(10))
>>> dd
<range_iterator object at 0x7fbd89751900>
>>> next(dd)
0
>>> next(dd)
1
>>> next(dd)
2
>>> next(dd)
3
>>> next(dd)
4
>>> next(dd)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

6 、


7 、常见库

7.1 、 request

Requests 2.28 [ 链接 ]

import requests
发送GET、POST、DEL请求
>>> r = requests.get('https://api.github.com/events')
>>> r = requests.post('https://httpbin.org/post', data={'key': 'value'})
>>> r = requests.post('https://httpbin.org/post', json={'key': 'value'})
>>> r = requests.delete('https://httpbin.org/delete')
发送带参数的URL请求
>>> payload = {'key1': 'value1', 'key2': ['value2', 'value3']}
>>> r = requests.get('https://httpbin.org/get', params=payload)

>>> print(r.url)
https://httpbin.org/get?key1=value1&key2=value2&key2=value3
发送差异化的URL请求
>>> header = {'user-agent': 'my-app/0.0.1'}
>>> time=0.001
>>> r = requests.get('https://httpbin.org/get', headers=headers, timeout=time)

>>> print(r.url)
https://httpbin.org/get?key1=value1&key2=value2&key2=value3
获得响应状态(200 OK 和 404 not found)
>>> good_r.status_code
>>> good_r.status_code == requests.codes.ok == int('200')
True
>>> bad_r.status_code
>>> bad_r.status_code == requests.codes.not_found == int('404')
True
读取响应状态并报错
>>> good_r.raise_for_status()
None
>>> bad_r.raise_for_status()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.8/dist-packages/requests/models.py", line 941, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: NOT FOUND for url: https://httpbin.org/status/404
获得响应内容(二进制原码)
>>> r.content
查看和修改默认识别的文本编码
>>> r.encoding
>>> r.encoding = 'utf-8'
获得响应内容(文本解码)
>>> r.text
获得响应内容(JSON解码)
>>> r.json
发送传输内容(上传)(非流式)
>>> url = 'https://httpbin.org/post'
>>> file = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}

>>> r = requests.post(url, files=file)
>>> r.text
{
  ...
  "files": {
    "file": "<censored...binary...data>"
  },
  ...
}
获得流式传输内容(下载)
>>> r = requests.get('https://api.github.com/events', stream=True)
>>> r.raw
<urllib3.response.HTTPResponse object at 0x7f3d192e71f0>
>>> r.raw.read(10)
'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'

with open(filename, 'wb') as fd:
    for chunk in r.iter_content(chunk_size=128):
        fd.write(chunk)
获得与发送 Cookie Sessioin
>>> url = 'https://httpbin.org/cookies'
>>> r = requests.get(url)
>>> r.cookies['example_cookie_name']
'example_cookie_value'

>>> cookis = dict(cookies_are='working')
>>> r = requests.get(url, cookies=cookie)
>>> r.text
'{"cookies": {"cookies_are": "working"}}'

>>> cookie2 = requests.cookies.RequestsCookieJar()
>>> cookie2.set('tasty_cookie', 'yum', domain='httpbin.org', path='/cookies')
>>> cookie2.set('gross_cookie', 'blech', domain='httpbin.org', path='/elsewhere')
>>> r = requests.get(url, cookies=jar)

>>> r = requests.Session().get(url, cookies=cookie)
URL重定向
>>> r = requests.get('http://github.com/')
>>> r.url
'https://github.com/'
>>> r.status_code
200
>>> r.history
[<Response [301]>]
>>> r = requests.get('http://github.com/', allow_redirects=False)
>>> r.status_code
301
>>> r.history
[]

7.2 、 json/yaml


7.3 、 re


7.4 、 string


7.5 、 random


7.6 、 datetime


7.7 、 logging


7.8 、 sys


7.9 、 bs4

Beautiful Soup 4.4.0 [ 链接 ]

from bs4 import BeautifulSoup

8 、


9 、相关链接

Python3 类型转换指南 [ 链接 ]

StarryVoid

Have a good time