python语言程序设计入门笔记
python语言程序设计
关舒文
第一章 程序设计方法
程序设计语言
程序设计语言包含 3 大类:
- 机器语言(一种二进制语言)
- 汇编语言
- 高级语言(包含C,C++,C#,Go等)
其中机器语言和汇编语言统称为低级语言
编译和解释
高级语言按照计算机执行方式不同可分为:
- 静态语言(C,C++,Java)
- 脚本语言(JavaScript,PHP,python)
静态语言采用编译运行(编译器执行编译),脚本语言采用解释(解释器直接解释)执行.
编译的好处
- 对于相同源代码,目标代码执行速度更快;
- 目标代码不需要解释器即可运行,在同类型操作系统上可灵活使用.
解释的好处
- 只需要保留原代码,程序纠错和维护十分方便;
- 只需要存在解释器,源代码可以在任何平台运行,可移植性较好.
第二章 python程序基本语法
程序的框架
python使用缩进来表明程序的格式框架
注释
使用#来表示单行注释,'''表示多行注释:
1 | |
命名与保留字
python语言允许使用大写字母,小写字母,数字,下划线,汉字等字符或字符组合给变量命名.不允许将数字用作名称首字符.变量命名区分大小写.特别的,变量命名不能与保留字相同(注意大小写):
| and | as | assert | break | class | continue |
|---|---|---|---|---|---|
| def | del | elif | else | except | finally |
| for | from | False | global | if | import |
| in | is | lambda | nonlocal | not | None |
| or | pass | raise | return | try | True |
| while | with | yield |
字符串索引与切片
索引操作
用双引号"或单引号'表示字符串,例如字符串"Hello"和'world'.对字符串
1 | |
的第一个字符'H'有两种索引方式:
1 | |
切片操作
我们可以通过切片操作来实现字符串的区间访问或列表的区间访问:
1 | |
start_index: 表示起始索引(包含该索引本身);该参数省略时,表示从对象"端点"开始取值,至于是从“起点”还是从"终点"开始,则由step参数的正负决定,step为正从"起点"开始,为负从"终点"开始.
end_index: 表示终止索引(不包含该索引本身);该参数省略时, 表示一直取到数据"端点", 至于是到"起点"还是到"终点", 同样由step参数的正负决定, step为正时直到"终点", 为负时直到"起点".
step: 正负数均可,其绝对值大小决定了切取数据时的"步长",而正负号决定了"切取方向",正表示"从左往右"取值,负表示"从右往左"取值.当step省略时,默认为1,即从左往右以增量1取值.
切片操作例子:
1 | |
赋值语句
python语言中,=用于赋值,即将等号右侧的计算结果赋值给左侧变量.例如:
1 | |
同步赋值语句:
1 | |
我们可以通过同步赋值语句来实现两个变量的交换:
1 | |
第三章 基本数据类型
数字类型
整数
默认情况下使用的是十进制,四种进制的表示如下表:
| 进制类型 | 引导符号 | 描述 | 例子 |
|---|---|---|---|
| 十进制 Decimal | 无 | 数字0-9组成 | 12345, 7829 |
| 二进制 Binary | 0b 或 0B | 数字0-1组成 | 0b101, 0B110 |
| 八进制 Octal | 0o 或 0O | 数字0-7组成 | 0o711, 0O127 |
| 十六进制 Hexadecimal | 0x 或 0X | 数字0-9,字母a-f(A-F)组成 | 0xABC |
浮点数
浮点数表示带有小数的数值,python要求浮点数必须带有小数部分以便区分浮点数和整数,有两种表示方法:
- 十进制表示法:
1999.0,0.0,-77.; - 科学计数法:
4.3e-3,9.6e5.
浮点数的特点
对于科学计数法 ,在python中系数最长可输出16个数字;十进制表示的浮点数最长可输出17个数字.
根据
sys.float_info的结果计算机能够提供15个数字的准确性,最后一位存在误差.
复数
python语言中,复数的虚数部分通过后缀"J"或"j"表示,复数表示采用以下形式:
1 | |
需要特别注意,复数类型中的实数部分和虚数部分都是浮点类型.
可以使用real操作获取复数实部,imag操作获取虚部:
1 | |
数字类型操作
内置数值运算操作符
| 操作符 | 描述 | 对应增强赋值操作符 |
|---|---|---|
| x - y | x与y之差 | -= |
| x * y | x与y之积 | *= |
| x + y | x与y之和 | += |
| x / y | x与y之商 | /= |
| x // y | x整除y | //= |
| x % y | x除以y的余数 | %= |
| x ** y | x的y次幂,即 | **= |
| 增强赋值操作符可简化代码表达: |
x op = y等价于x = x op y,其中op为增强复制操作符
| 函数 | 描述 | 输出 |
|---|---|---|
| abs(x) | x的绝对值,若x为复数则返回模 | 数值 |
| divmod(x, y) | 返回包含整除,求余结果的二元组形式(也称为元组类型) | (x//y,x%y) |
| pow(x, y[, z]) | (X**y)%z,即 pow(x,y),它与x**y相同 | 数值 |
| round(x[, ndigits]) | 对x四舍五入,保留 ndigits 位小数.round(x)返间四舍五入的整数 | 数值 |
| max(x1,x2,…,xn) | 值x1,x2,…,xn的最大值,n没有限定co | 数值 |
| min(x1,x2,…,xn) | 值x1,x2,…,xn的最大值,n没有限定 | 数值 |
特别的,pow()函数的第三个参数在加解密算法中十分重要,见如下对比: |
1 | |
内置数字类型转换
| 函数 | 合法输入 | 输出 |
|---|---|---|
| int(x) | 浮点数,整数,字符串 | 整数 |
| float(x) | 浮点数,整数,字符串 | 浮点数 |
| complex(实部[,虚部]) | 实部:整数,浮点数,字符串;虚部:整数,浮点数(不允许字符串) | 复数 |
int()会对浮点数进行截尾,不进行四舍五入操作;
int(),float()不允许输入复数.
math库
常用数学常数:
| 常数 | 数学表示 | 描述 |
|---|---|---|
| math.pi | 圆周率 | |
| math.e | 自然对数 | |
| math.inf | 正无穷大 | |
| math.nan | 非浮点数标记,NaN | |
| 数值函数: |
| 函数 | 数学表示 | 描述 |
|---|---|---|
| math.fabs(x) | x的绝对值 | |
| math.fmod(x,y) | % | x求余y |
| math.fsum([x,y,…]) | 浮点数精确求和 | |
| math.ceil(x) | 向上取整 | |
| math.floor(x) | 高斯取整 | |
| math.factorial(x) | x的阶乘 | |
| math.gcd(a,b) | a,b的公约数 | |
| math.isfinite(x) | 当x不是无穷大或NaN时为真 | |
| math.isnan(x) | 当x是NaN时为真 | |
| 幂对数函数: |
| 函数 | 数学表示 | 描述 |
|---|---|---|
| math.pow(x,y) | x的y次幂 | |
| math.exp() | e的x次幂 | |
| math.sqrt() | x的平方根 | |
| math.log(a[,b]) | a以b为底的对数,b省略时为x | |
| 三角运算: |
| 函数 | 数学表示 | 描述 |
|---|---|---|
| math.degrees(x) | 弧度转角度 | |
| math.radians(x) | 角度转弧度 | |
| math.hypot(x,y) | 坐标(x,y)离原点距离 |
字符串类型和基本操作
字符串的表示
- 单引号表示
'hello' - 双引号表示
"hello" - 三引号表示
'''hello'''
- 单引号或双引号都可以作为字符串的一部分,例如
1
'you can print "hello" by "print("hello")"' # 反正就是可以套娃啦 - 三引号可用于表示多行字符串,也可以用于表示多行注释(必须以
'''开头)1
2
3
4
5
6
7>>> print('''
hello
world
''')
# 注意:此处为空行, '''后的第一个字符为换行符"\n"
hello
world
字符串的输入
输入语法:
1 | |
例如:
1 | |
字符串操作
基本字符串操作符:
| 操作符 | 描述 |
|---|---|
| x + y | 连接两个字符串x与y |
| x * n 或 n * x | 复制n次字符串x |
| x in s | 如果x是s的子串, 返回True |
| str[i] | 否则返回False 索引, 返回第t个字符 |
| str[N:M] | 切片, 返回索引第N到第M的子串, 其中不包含M |
| 特殊格式化控制字符: |
| 操作符符 | 作用 |
|---|---|
| \a | 蜂呜, 响铃. |
| \b | 回退, 向后退一格. |
| \f | 换页. |
| \n | 换行, 光标移动到下行首行. |
| \r | 回车, 光标移动到本行首行. |
| \t | 水平制表. |
| \v | 垂直制表. |
| \0 | NULL,什么都不做. |
内置字符串处理函数
| 函数 | 描述 |
|---|---|
| len(x) | 返回字符串 x 的长度, 也可返回其他组合数据类型元素个数 |
| str(x) | 返回任意类型 x 所对应的字符串形式 |
| chr(x) | 返回Ascii编码x 对应的单字符 |
| ord(x) | 返回单字符表示的Asciii编码 |
| hex(x) | 返回整数 x 对应十六进制数的小写形式字符串 |
| oct(x) | 返回整数 x 对应八进制数的小写形式字符串 |
ASCII码表中: 大写字母
A~Z对应65~90,小写字母a~z对应97~122
内置字符串处理方法
↓—编者水平有限,该段内容存在问题,有待研究,请跳过—
python中对数据的处理可分为函数与方法.函数常以<库>.<函数>(待处理对象)的形式实现
1 | |
方法常为面向对象的,其通常以<对象>.<方法>(方法选项)
1 | |
当然,方法与函数都可看作为函数,只不过他们的定义方式有所不同.
↑—编者水平有限,该段内容存在问题,有待研究,请跳过—
常用的内置字符串处理方法(str表示字符串变量)
| 方法 | 描述 |
|---|---|
| str.lower() | 返回字符串str的副本, 全部字符小写 |
| str.upper() | 返回字符串str的副本, 全部字符大写 |
| str.islower() | 当str所有字符都是小写时为真 |
| str.isprintable() | 当str所有字符都是可打印的时候为真 |
| str.isnumeric() | 当str所有字符都是数字的时候为真 |
| str.isspace() | 当str所有字符都是空格,返回True, 否则返回False |
| str.endswith(suffix [,start[,end]]) | str[start: end]以suffix结尾返回True, 否则返回False |
| str.startswith(prefix[,start[,end]]) | str[start: end]以prefix开始返回True, 否则返回False |
| str.split(sep=None, maxsplit=-1) | 返回一个列表,由str根据sep被分隔的部分构成 |
| str.count(sub[,start[,end]]) | 返回str[start: end]中sub子串出现的次数 |
| str.replace(old, new[, count]) | 返回字符串str的副本, 所有old子串被替换为new, 如果count给出, 则前count次old出现被替换 |
| str.center(width[,fillchar]) | 字符串居中函数,返回长度为width得字符串,str位于中间位置,以fillchar填充两边 |
| str.strip([chars]) | 返回字符串str的副木, 在其左侧和右侧去掉chars中列出的字符 |
| str.zfill(widlh) | 返回字符串str的副本, 长度为width,不足部分在左侧补0,如果左侧为"+“,”-"则从第二个字符开始补0 |
| str.format() | 返回字符串str的一种排版格式 |
| str.join(iterable) | 返回一个新字符串, 由组合数据类型terable变址的每个元素组成, 元素间用str分隔 |
| 例子: |
1 | |
字符串的format()格式化
format()方法的使用
基本格式:
1 | |
该方法的基本思想是将format()方法中用逗号分隔的参数按照序号关系替换到模板字符串的槽中,槽用大括号{}表示.大括号中可以指定使用参数的序号,按照序号替换.注意format()中的序号从0开始.
实例:
1 | |
槽的格式控制
我们可以在槽中输入各种控制字符以进行字符格式化:
1 | |
示例:
1 | |
- 引导符号 : 用
:来引导后续格式控制标记 - 填充 指定宽度(必须指定对齐方式)内除了参数外的字符采用什么方式表示, 默认采用空格,可以通过填充替换,
- 对齐
<左对齐,>右对齐,^居中对齐 - 宽度 指当前槽的设定输出字符宽度, 如果该槽对应的format()参数长度比<宽度>设定值大, 则使用参数实际长度;如果该值的实际位数小于指定宽度, 则位数将以填充字符串进行补充.
- 千分位分隔符 以逗号作为千分位分割符(输入
,) - 精度 以
.开头后加数字.对于浮点数,表示输出的有效位数,对于字符串表示最大输出长度(超出部分被截尾) - 类型
- 对于整数类型:
- b: 输出整数的二进制方式.
- C: 输出整数对应的Unicode字符.
- d: 输出整数的十进制方式.
- 0: 输出整数的八进制方式.
- X: 输出整数的小写十六进制方式.
- X: 输出整数的大写十六进制方式.
- 对于浮点数类型:
- e: 输出浮点数对应的小写字母e的指数形式.
- E: 输出浮点数对应的大写字母E的指数形式.
- f: 输出浮点数的标准浮点形式.
- %: 输出浮点数的百分形式.
- 对于整数类型:
第四章 程序的控制结构
if条件语句
1 | |
- 如果
<condition_1>为 True 将执行<statement_block_1>块语句 - 如果
<condition_1>为False, 将判断<condition_2> - 如果
<condition_2>为 True 将执行<statement_block_2>块语句 - 如果
<condition_2>为False, 将执行<statement_block_3>块语句if常用的操作符:
| 操作符 | 描述 |
|---|---|
| < | 小于 |
| <= | 小于或等于 |
| > | 大于 |
| >= | 大于或等于 |
| == | 等于, 比较两个值是否相等 |
| != | 不等于 |
循环语句
for循环
1 | |
当for循环正常执行之后, 程序会继续执行else语句中的内容,若循环非正常退出则不执行.
while循环
1 | |
当while循环正常退出(此时<expr>的值为False)后,将会执行else语句中的内容.
特别的,我们可以通过创造永真的条件<expr>来实现无限循环,示例:
1 | |
循环保留字: break, continue
循环结构有两个保留字: break 和 continue, 它们用来辅助控制循环执行. 具体作用如下:
break语句可以跳出 for 和 while 的循环体. 如果你从 for 或 while 循环中终止, 任何对应的循环 else 块将不执行.continue语句被用来告诉 Python 跳过当前循环块中的剩余语句, 然后继续进行下一轮循环.
函数: range()
在for循环中可用range()指定循环遍历的范围.用法:
1 | |
以下 n,a,b,x 均为整数
range(n)(仅指定结束数值)表示取整数range(a, b)(指定起始数值)表示取整数range(a, b, x)表示取整数(其中)
random库的使用
| 函数 | 描述 |
|---|---|
| seed(a=None) | 初始化随机数种子, 默认值为当前系统时间 |
| random() | 生成一个[0.0,1.0)之间的随机小数 |
| randint(a, b) | 生成一个[a,b]之间的整数 |
| getrandbits(k) | 生成一个K比特长度的随机整数 |
| randrange(start, stop[, step]) | 生成一个[start, stop)之间以step为步数的随机整数 |
| uniform(a, b) | 生成一个[a, b]之间的随机小数 |
| choice(seq) | 从序列类型, 例如列表中随机返回-个元素 |
| shuffle(seq) | 将序列类型中的元素随机排列, 返回打乱后的序列 |
| sample(pop, k) | 从pop类型中随机选取k个元素,以列表类型返回 |
生成随机数之前可以通过
seed()函数指定随机数种子,随机数种子一般是一个整数, 只要种子相同, 每次生成的随机序列也相同. 这种情况便于测试和同步数据
异常处理
1 | |
可以使用except...as..:语句实现将错误信息返回至一个变量的效果
1 | |
可以实现将所有错误信息返回至err并打印.
以下是常见的错误代码:
| 异常代码 | 异常原因 |
|---|---|
| AttributeError | 属性错误, 特性引用和赋值失败时会引发属性错误 |
| NameError | 试图访问的变量名不存在 |
| SyntaxError | 语法错误, 代码形式错误 |
| Exception | 所有异常的基类, 因为所有python异常类都是基类Exception的其中一员, 异常都是从基类Exception继承的, 并且都在exceptions模块中定义. |
| IOError | 一般常见于打开不存在文件时会引发IOError错误, 也可以解理为输出输入错误 |
| KeyError | 使用了映射中不存在的关键字(键)时引发的关键字错误 |
| IndexError | 索引错误, 使用的索引不存在, 常索引超出序列范围, 什么是索引 |
| TypeError | 类型错误, 内建操作或是函数应于在了错误类型的对象时会引发类型错误 |
| ZeroDivisonError | 除数为0, 在用除法操作时, 第二个参数为0时引发了该错误 |
| ValueError | 值错误, 传给对象的参数类型不正确, 像是给int()函数传入了字符串数据类型的参数. |
异常抛出
使用raise保留字来抛出异常,常用于try语句中自定义返回错误:
1 | |
示例:
1 | |
也可以结合try语句使用
1 | |
第五章 函数与代码复用
定义函数
Python 定义函数使用 def 保留字, 一般格式如下:
1 | |
注意:
- 函数代码块以 def 关键词开头, 后接函数标识符名称和圆括号 ().
- 任何传入参数和自变量必须放在圆括号中间, 圆括号之间可以用于定义参数.
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明.
- 函数内容以冒号起始, 并且缩进.
return [表达式]结束函数, 选择性地返回一个值给调用方. 不带表达式的return相当于返回 None.
调用函数
函数的调用过程
- 调用程序在调用处暂停执行.
- 在调用时将实参复制给函数的形参.
- 执行函数体语旬.
- 函数调用结束给出返回值, 程序回到调用前的暂停处继续执行.
函数的调用方式
1 | |
例如:
1 | |
参数传递
在 python 中, 类型属于对象, 变量是没有类型的:
1 | |
以上代码中, [1,2,3] 是 List 类型, “hello” 是 String 类型, 而变量 a 是没有类型, 她仅仅是一个对象的引用(一个指针), 可以是指向 List 类型对象, 也可以是指向 String 类型对象.
可更改(mutable)与不可更改(immutable)对象
在 python 中, strings, tuples, 和 numbers 是不可更改的对象, 而 list,dict 等则是可以修改的对象.
不可变类型: 变量赋值 a=5 后再赋值 a=10, 这里实际是新生成一个 int 值对象 10, 再让 a 指向它, 而 5 被丢弃, 不是改变 a 的值, 相当于新生成了 a.
可变类型: 变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改, 本身la没有动, 只是其内部的一部分值被修改了.
**python 函数的参数传递: **
不可变类型: 类似 C++ 的值传递, 如 整数、字符串、元组. 如 fun(a), 传递的只是 a 的值, 没有影响 a 对象本身. 如果在 fun(a))内部修改 a 的值, 则是新生成来一个 a. 示例(
id()函数可显示内存地址):1
2
3
4
5
6
7
8def change(a):
print(id(a)) # 指向的是同一个对象
a=10
print(id(a)) # 一个新对象
a=1
print(id(a))
change(a)返回:
1
2
394127348335360
94127348335360
94127348335648可以看见在调用函数前后, 形参和实参指向的是同一个对象(对象 id 相同), 在函数内部修改形参后, 形参指向的是不同的 id.
可变类型: 类似 C++ 的引用传递, 如 列表, 字典. 如 fun(la), 则是将 la 真正的传过去, 修改后 fun 外部的 la 也会受影响.示例:
1
2
3
4
5
6
7
8
9
10def changeme( mylist ):
"修改传入的列表"
mylist.append([1,2,3,4])
print ("函数内取值: ", mylist)
return
# 调用changeme函数
mylist = [10,20,30]
changeme( mylist )
print ("函数外取值: ", mylist)返回:
1
2函数内取值: [10, 20, 30, [1, 2, 3, 4]]
函数外取值: [10, 20, 30, [1, 2, 3, 4]]传入函数的和在末尾添加新内容的对象用的是同一个引用. 故输出结果相同.
鉴于传递的特征,我们可以使用global <变量>声明来将局部变量的改变应用到全局变量中.
参数
以下是调用函数时可使用的正式参数类型:
- 必需参数
- 关键字参数
- 默认参数
- 不定长参数
必需参数
1 | |
该函数中参数a已被调用,故使用该函数时必须输入参数a,这种参数称为必须参数.必需参数须以正确的顺序传入函数. 调用时的数量必须和声明时的一样.
关键字参数
关键字参数和函数调用关系紧密, 函数调用使用关键字参数来确定传入的参数值. 使用关键字参数允许函数调用时参数的顺序与声明时不一致, 因为 Python 解释器能够用参数名匹配参数值. 使用方法:
1 | |
默认参数(可选参数)
调用函数时, 如果没有传递参数, 则会使用默认参数. 可以通过指定参数的默认值,来避免没有该参数输入时发生错误.
1 | |
返回:
1 | |
不定长参数(可变数量参数)
当我们需要一个函数能处理比当初声明时更多的参数. 这些参数叫做不定长参数.
带一个
*的不定长参数: 通过在最后一个参数前增加*实现.
特点:- 不定长参数一定为最后一个参数
- 该参数将会以
元组的形式传入函数 - 如果在函数调用时没有指定参数, 它就是一个空元组. 我们也可以不向函数传递未命名的变量
示例:
1
2
3
4
5
6
7def mean(a,*b):
'求平均值'
for i in b:
a+=i
print(a/(len(b)+1))
mean(1)
mean(1,2,3,4))返回:
1
21.0
2.5带两个
*的不定长参数: 通过在最后一个参数前增加**实现.
区别:- 该参数将会以
字典的形式传入函数
1
2
3
4
5
6
7
8def printinfo( arg1, **vardict ):
"打印任何传入的参数"
print ("输出: ")
print (arg1)
print (vardict)
# 调用printinfo 函数
printinfo(1, a=2,b=3)返回:
1
21
{'a': 2, 'b': 3}- 该参数将会以
*单独出现的不定长参数 声明函数时, 参数中星号*可以单独出现,如果单独出现星号 ,*后的参数必须用关键字参数方式传入. 示例:1
2
3
4
5
6
7
8
9
10
11>>> def f(a,b,*,c):
return a+b+c
>>> f(1,2,3) # 报错
------------------------------------------
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() takes 2 positional arguments but 3 were given
>>> f(1,2,c=3) # 正常
6
匿名函数
定义方法:
1 | |
特点:
- lambda 只是一个表达式, 函数体比 def 简单很多.
- lambda的主体是一个表达式, 而不是一个代码块. 仅仅能在lambda表达式中封装有限的逻辑进去.
- lambda 函数拥有自己的命名空间, 且不能访问自己参数列表之外或全局命名空间里的参数.
代码复用与模块化设计
模块化设计指通过函数或对象的封装功能将程序划分成主程序、子程序和子程序间关系的表达. 模块化设计是使用函数和对象设计程序的思考方法, 以功能块为基本单位, 一般有以下两个基本要求.
- 紧耦合: 尽可能合理划分功能块, 功能块内部耦合紧密.
- 松耦合: 模块间关系尽可能简单, 功能块之间耦合度低.
使用函数只是模块化设计的必要不充分条件, 根据计算需求合理划分函数十分重要. 一般来说, 完成特定功能或被经常复用的一组语句应该采用函数来封装, 并尽可能减少函数间参数和返回值的数量.
函数的递归
我们看看数学中的递归:
称为递归的基例,我们可以用python函数实现以上的思想:
例1: 计算阶乘
数学表述:
python实现:
1 | |
输出:
1 | |
例2: 汉诺塔问题
有三个立柱A、B、C. A柱上穿有大小不等的圆盘N个, 较大的圆盘在下, 较小的圆盘在上. 要求把A柱上的圆盘全部移到C柱上, 保持大盘在下、小盘在上的规律(可借助B柱). 每次移动只能把一个柱子最上面的圆盘移到另一个柱子的最上面. 请输出移动过程.
递归逻辑:
A, B, C三个圆柱, 分别为初始位, 过渡位, 目标位, 设A柱为初始位, C位为最终目标位
- 将最上面的n-1个圆盘从初始位移动到过渡位
- 将初始位的最底下的一个圆盘移动到目标位
- 将过渡位的n-1个圆盘移动到目标位
python实现:
1 | |
递归特点
- 递归必须设计基例
- 递归深度不应超出1000层,若有需要可通过以下代码更改最大层数.
1
2import sys
sys.setrecursionlimit(<新的层数限制>)
第六章 组合数据类型
序列类型

序列类型特点:
- 所有序列类型都可以使用相同的索引体系
- 所有序列类型均支持成员关系操作符
in,长度计算函数len(),切片[M:N:step] - 元素自身亦可以为序列类型
序列类型的通用操作符或函数:
| 操作符 | 描述 |
|---|---|
| x in s | 如果x是s的元素,返回True,否则返回False |
| x not in s | 如果x不足s的元素, 返回True, 否则返同False |
| s+t | 连接s和t |
| s * n 或 n* s | 将序列s复制n次 |
| s[i] | 索引,返回序列的第i个元素 |
| s[i: j] | 分片,返回包含序列s第i到j个元素的子序列(不包含第j个元素) |
| s[i: j: k] | 步骤切片, 返回包含序列s第i到j个元素以k为步数的子序列 |
| len(s) | 序列s的元素个数(长度) |
| min(s) | 序列s中的最小元素 |
| max(s) | 序列s中的最大元素 |
| s.index(x[, i[, j]]) | 序列s中从1开始到j位置中第一次出现元素x的位置 |
| s.count(x) | 序列s中出现x的总次数 |
元组
元组采用逗号,和圆括号(非必须)()来表示:
1 | |
注意: 元组一旦被创建就不能修改
列表
列表具有可修改的特性故除了序列操作,还有以下操作:
| 方法 | 描述 |
|---|---|
| list.append(x) | 把一个元素添加到列表的结尾, 相当于 a[len(a):] = [x]. |
| list.extend(L) 或 list += L | 通过添加指定列表的所有元素来扩充列表, 相当于 a[len(a):] = L. |
| list.insert(i, x) | 在指定位置插入一个元素. 第一个参数是准备插入到其前面的那个元素的索引, 例如 a.insert(0, x) 会插入到整个列表之前, 而 a.insert(len(a), x) 相当于 a.append(x) . |
| list.remove(x) | 删除列表中值为 x 的第一个元素. 如果没有这样的元素, 就会返回一个错误. |
| list.pop([i]) | 从列表的指定位置移除元素, 并将其返回. 如果没有指定索引, a.pop()返回最后一个元素. 元素随即从列表中被移除. |
| list.clear() | 移除列表中的所有项, 等于del a[:]. |
| list.index(x) | 返回列表中第一个值为 x 的元素的索引. 如果没有匹配的元素就会返回一个错误. |
| list.count(x) | 返回 x 在列表中出现的次数. |
| list.sort() | 对列表中的元素进行排序. |
| list.reverse() | 倒排列表中的元素. |
| list.copy() | 返回列表的浅复制, 等于a[:]. |
列表的复制
从上表可以知道,我们可以使用list.copy()来复制列表,不妨考虑如下两种情况:
情况 1
1 | |
输出
1 | |
我们发现这种赋值方式将会导致两个列表变量指向同一个内存指针,对其中一个修改,将会导致两个变量均发生变化.
情况 2
1 | |
输出:
1 | |
list.copy()方法将会产生一个新的列表变量,其指向不同的内存指针,两者互相独立不相互改变
关于这两种情况,我们可以稍微引申一下:
1 | |
输出:
1 | |
当我们未对变量 b 进行修改时, b与a指向相同的地址,但当我们对b作出修改,此时a,b不再关联.
列表的递推公式
每个列表递推公式都在 for 之后跟一个表达式, 然后有零到多个 for 或 if 子句. 返回结果是一个根据表达从其后的 for 和 if 上下文环境中生成出来的列表. 如果希望表达式推导出一个元组, 就必须使用括号. 语法如下:
1 | |
例 1
小明和小红丢骰子,问小明的点数比小红大的概率是多少?
解 小明和小红丢骰子丢出的点数相互独立,故他们可取以下值:
1 | |
设小明点数比小红大的事件为,则
1 | |
可以求出事件发生的概率为:
1 | |
列表的排序 list.sort()方法与sorted()函数
列表的排序有两种处理方式,分别是list.sort()方法与sorted()函数.他们有如下区别
**
.sort()与sorted()区别: **
sort是应用在 list 上的方法,sorted可以对所有可迭代的对象进行排序操作. list 的sort方法返回的是对已经存在的列表进行操作, 无返回值, 而内建函数sorted方法返回的是一个新的 list, 而不是在原来的基础上进行的操作.
关于该区别,有以下辨识:
1 | |
该程序的输出应为None,猜错的小伙伴要再去看看上面的区别啦😜.sort()方法是没有返回值的,结果咧,你print了个寂寞.
list.sort()方法语法
1 | |
- key 通过函数来指定可迭代对象中的一个元素来进行排序;
- reverse 决定排序是否反向,默认为
False
示例:
1 | |
返回:
1 | |
sorted()函数语法
1 | |
使用方法同上.
del 语句
使用 del 语句可以从一个列表中依索引而不是值来删除一个元素. 这与使用 pop() 返回一个值不同. 可以用 del 语句从列表中删除一个切片, 或清空整个列表(del a[:])而不删除该列表变量. 例如:
1 | |
集合
集合的定义类似于数学上的定义,有以下特点:
- 集合是无序组合,没有索引与位置的概念,不支持切片;
- 集合中的元素是不能重复的(可利用该特征过滤重复元素);
- 打印出的集合会按照一定规律排列,不一定与定义顺序一致.
集合的表示与生成
使用大括号{}表示的数组称为集合,例如:
1 | |
为一个集合.
使用set()来生成集合,示例如下:
1 | |
集合类型的操作符
| 操作符 | 描述 |
|---|---|
| S - T 或 S.difference(T) | |
| S -= T 或 S.difference_update(T) | |
| S & T 或 S.intersection(T) | |
| S&=T 或 S.intersectionupdate(T) | |
| S^T 或 s.symmetric_ difference(T) | |
| S^=T 或 s.symmetric_difference_update(T) | |
| S|T 或 S.union(T) | |
| S|=T 或 S.update{T) | |
| S<=T 或 S.issubset(T) | 当 时为真 |
| S<T | 当 时为真 |
| S>=T 或 S.issuperset(T) | 当 时为真 |
| S>T | 当 时为真 |
![]() | |
| 集合类型的操作函数或方法 |
| 操作函数或方法 | 描述 |
|---|---|
| S.add(x) | 如果数据项x不在集合S中, 将x增加到s |
| S.clear() | 移除S中的所有数据项 |
| S.copy() | 返回集合S的一个副本 |
| S.pop() | 随机返回集合S中的一个元素, 如果S为空, 产生KeyError异常 |
| S.discard(x) | 如果x在集合S中, 移除该元素 |
| S.remove(x) | 如果x在集合S中, 移除该元素 |
| S.isdisjoint(T) | 如果集合S与T没有相同元素, 返回True |
| len(S) | 返同集合S的元素个数 |
| X in S | 如果x是S的元素, 返回True, 否则返回False |
| x not in S | 如果x不是S的元素, 返回True, 否则返回False |
字典
在python中我们可以把字典看作键值对的集合(他们是不同的数据结构,字典不属于集合),
特点:
- 序列是以连续的整数为索引, 与此不同的是, 字典以关键字为索引, 关键字可以是任意不可变类型, 通常用字符串或数值.
- 字典键值对之间没有顺序也不能重复
- 字典的键必须是
元组,字符串,数字;不允许使用列表,字典,集合作为键.
字典的创建
使用
{}创建空字典1
dictionary = {}使用函数
dict()直接从键值对元组列表中构建字典1
2>>> dict([('萝卜', '🥕'), ('香蕉', '🍌'), ('苹果', '🍎')])
{'萝卜': '🥕', '香蕉': '🍌', '苹果': '🍎'}使用递推公式生成键和值
1
2
3
4>>> parrot = {str(x)+'个萝卜🥕': str(x)+'个坑' for x in ['一', '两', '三']}
>>> print(parrot)
{'一个萝卜🥕': '一个坑', '两个萝卜🥕': '两个坑', '三个萝卜🥕': '三个坑'}当键只是简单的字符串, 使用键参数指定键值
1
2>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'jack': 4098, 'guido': 4127}
字典的访问
通过索引符号实现:
1 | |
当找不到该键时,将会返回KeyError.该访问方式也可以修改或添加键值对
1 | |
字典的操作
| 函数和方法 | 描述 |
|---|---|
| <d>.keys() | 返回所有的键信息 |
| <d>.values() | 返回所有的值信息 |
| <d>.items() | 返回所有的键值对 |
| <d>.get(<key>,<default>) | 键存在则返回相应值, 否则返回默认值 |
| <d>.pop(<key>, <default>) | 键存在则返回相应值, 同时删除键们对, 否则返回默认值 |
| <d>.popitem() | 随机从字典中取出一个键值对, 以元组(key, value)形式返回 |
| <d>.clear() | 删除所有的键值对 |
| del <d>[<key>] | 删除字典中某一个键值对 |
| <key> in <d> | 如果键在字典中则返回True, 否则返回False |
需要注意的是.keys(),.values(),.items()他们的输出类型不是列表,我们可以使用list()函数来返回列表:
1 | |
输出:
1 | |
注意观察他们的输出类型.
例子 : 词频统计
可以利用字典键不重复的特性进行词频统计,建立{单词:词频}的映射,思路如下:
1 | |
遍历
在字典中遍历时, 键值对可以使用items()方法同时解读出来:
1 | |
在序列中遍历时, 索引位置和对应值可以使用enumerate()函数同时得到:
1 | |
同时遍历两个或更多的序列, 可以使用zip()组合:
1 | |
要反向遍历一个序列, 首先指定这个序列, 然后调用reversed() 函数:
1 | |
第七章 文件和数据格式化
文件的打开关闭
python使用open()方法实现文件的打开,打开文件之前需保证文件不被占用(否则返回OSError),若文件被python占用,需使用close()解除占用.语法格式:
1 | |
<mode>处用于指定文件的打开方式,有如下打开方式:
| 文什的打开模式 | 含义 |
|---|---|
| ‘r’ | 只读校式, 如果文件不存在, 返回异常FileNotFoundError,默认值 |
| ‘w’ | 覆盖写模式, 指针会从第一行行首开始覆写,文件不存在则创建, 存在则完全疫盖 |
| ‘x’ | 创建马模式, 文件不存在则创建, 存在则返同异常FileExistsError |
| ‘a’ | 追加写模式, 文件不存在则创建, 存在则在文件最后追加内容 |
| ‘b’ | 二进制文件模式 |
| ‘t’ | 文本文件模式, 默认值 |
| ‘+’ | 与r/w/x/a 一同使用, 在原功能基础上增加同时读写功能 |
以上打开方式可以组合使用,打开后记得使用close()方法释放. | |
| 示例: |
1 | |
文件的读写
注意文件读写过程中,每一行都可能需要换行符.读取时记得删除换行符,写入时记得按照需求添加换行符.换行符是真实存在的字符,只不过看不见而已啦.
读取
| 操作方法 | 含义 |
|---|---|
| <file>.readall() | 读入整个文件内容, 返回-个字符串或字节流 |
| <file>.read(size=-1) | 从文件中读入整个文件内容, 如果给出参数, 读入前size长度的字符串或字节流 |
| <file>.readline(size=-1) | 从文件中读入一行内容, 如果给出参数, 读入该行前size长度的字符串或字节流 |
| <file>.readlines(hint=-1) | 从文件中读入所有行, 以每行为元素形成一个列表, 如果给出参数, 读入hint行 |
我们常用以下方式(python此时将文件看作一个行序列,通过遍历进行读取)来逐行读入并修改,这样可以避免一次性读入过多内容影响内存性能:
1 | |
这样就可以把一本超炮打印出来啦…
写入
| 写入方法 | 含义 |
|---|---|
| <file>.write(s) | 向文件写入一个字符串或字节流 |
| <file>. writelines(Lines) | 将一个元素全为字符串的列表写入文件 |
| <file>.seek(offset) | 改变当前文件操作指针的位置, offset的值: 0-文件开头: l一当前位置: 2一文件结尾 |
