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一文件结尾 |