# Python 期末复习

# 变量

# 案例一

1
2
3
4
5
  
a = 'hello'
b = a
a = 'world'
print(b)
结果为

hello
原因:一切数据皆对象,变量指向数据对象

# 案例二

1
2
3
4
5
6
7
8
9
  
x1 = [1, 2]
x2 = [1, 2]
x1 is x2
x3 = x2
x2 is x3
x2.append(3)
print(x2)
print(x3)
结果为

False
True
[1, 2, 3]
[1, 2, 3]
原因:x1 和 x2 是两个地址,让 x2 = [1, 2] 实际上是让 x2 指向了一个新的对象(虽然这个对象和 x1 的值一样),但是如果写成 x3 = x2 的话,意思就是 x3 指向 x2 的对象,这个时候修改 x2 那么 x3 也会一起变化。

# 案例三

1
2
3
4
5
6
  
x1 = [1, 2]
x2 = x1
x1 = 6
print(x1)
print(x2)
结果为

6
[1, 2]
原因:给 x1 重新赋值的时候,相当于 x1 指向了新的对象 6,但是 x2 还是指向 [1, 2]

# 序列

# 列表 List

列表是由一系列按照特定顺序排列的元素组成的可变序列

# 案例一

1
2
3
4
5
  
a = [1, 2, 3, 4]
for x in a:
a.remove(x)
print(a)
结果为

[2, 4]
原因:x 依次取 a 中的第 1,2…… 个元素(是以 remove 后的新列表为标准的)

# 案例二

1
2
3
4
5
  
a = [1, 2, 3, 4]
for x in a:
a.pop()
print(a)
结果为

[1, 2]
原因:pop () 括号中没有参数的时候,删除列表最后一个元素,第三次循环的时候列表没有第三个元素了所以结束循环。

# 案例三

1
2
3
4
5
  
a = [1, 2, 3, 4]
for x in range(len(a)):
del a[0]
print(a)
结果为

[]
原因:x 依次取 1, 2, 3, 4, 循环四次故元素被删除干净。

# 元组 tuple

元组是由一系列按特定顺序排列的元素组成的不可变序列

  • 不可变对象:对象存放在地址中的值不会改变,所谓的改变是创建了一个新地址放新对象。
1
2
3
4
 
a = 1
b = 1
a is b
结果为

True

  • 可变对象:对象存放在地址中的值会原地改变,对于相同的值的不同对象,内存中会存在不同的对象(比如列表和下面的例子)
1
2
3
4
 
a = [1, 2]
b = [1, 2]
a is b
结果为

False

# 案例一

1
2
3
4
5
6
 
a = ['jn', 'wh']
b = ['jn', 'wh']
c = a
a += ['qd']
print(a, b, c)
结果为

[‘jn’, ‘wh’, ‘qd’][‘jn’, ‘wh’][‘jn’, ‘wh’, ‘qd’]

注意,创建一个元素的元组要加逗号

1
2
  
A = ('山东大学',)

# 字典 dictionary

字典是无序的可变序列,保存的内容是以键值对的形式存放的,可以一个键对多个值
字典又称关联数组或者散列表

  • 字典的内容好多啊,不想打了,去看 ppt 吧

# 集合 set

集合是无序不重复的元素组合

  • 可变集合 set
  • 不可变集合 frozenset

# 总结

数据结构 是否可变 是否重复 是否有序 定义符号
列表 list 可变 可重复 有序 []
元组 tuple 不可变 可重复 有序 ()
字典 dictionary 可变 可重复 无序
集合 set 不可变 不可重复 无序 {}

# 函数

# 参数传递

  • 当实际参数为不可变对象时,进行值传递;当实际参数为可变对象时,进行引用传递;
  • 值传递后,改变形参的值,实参的值不变;引用传递后,改变形参的值,实参也发生变化;

# 案例一

1
2
3
4
5
6
  
def test(a):
a = 10
b = 2
test(b)
print(b)
结果为

2
原因:不可变对象,形参 a 改变,实参 b 不改变

# 案例二

1
2
3
4
5
6
7
8
9
10
11
  
def test(a):
a += a
mot = 'asd'
print(mot)
test(mot)
print(mot)
list = ['a', 'b']
print(list)
test(list)
print(list)
结果为

asd
asd
[‘a’, ‘b’]
[‘a’, ‘b’, ‘a’, ‘b’]
原因:不可变对象字符串是值传递,原值不改变;可变对象列表是引用传递,原值一起改变。

# 案例三

1
2
3
4
5
6
  
def test(l=[]):
l.append('sdu')
return l
print(test())
print(test())
结果为

[‘sdu’]
[‘sdu’, ‘sdu’]
原因:默认参数 l 已经发生改变

# 案例四

1
2
3
4
5
6
7
8
  
def test(l=None):
if l is None:
l = []
l.append('sdu')
return l
print(test())
print(test())
结果为

[‘sdu’]
[‘sdu’]

# 变量的作用域

  • 当局部变量与全局变量重名时,对函数体的变量赋值,不影响函数体外的变量
  • 函数内部的变量名如果第一次出现且出现在 = 前面,则其为局部变量;如果第一次出现且出现在 = 后面,且该变量在全局中已定义,则为引用全局变量。

# 案例一

1
2
3
4
5
6
  
a = 10
def test():
a = a + 1
print(a)
test()
结果为

Error
原因:没有定义 test () 里面的第一个 a(等号左边的 a)

# 案例二

1
2
3
4
5
6
  
a = 10
def test():
s = a + 1
print(s)
test()
结果为

11
原因:正常函数输出

# 案例三

1
2
3
4
5
6
7
8
9
  
a = [1, 2, 3]
b = [4, 5, 6]
def test01():
print(a)
def test02():
a = b
test02()
test01()
结果为

[1, 2, 3]
原因:test02 () 把全局变量 b 赋值给 test02 里的局部变量 a,但是 test01 () 调用的还是全局变量 a。

# 字符串

# 字符串的常用功能

# 拼接

1
2
3
4
 
a = 'hello'
b = 'world'
print(a + b)
结果为

helloworld

# 计算字符串长度

1
2
3
4
5
 
a = '20级人工智能自动化'
print(len(a))
print(len(a.encode()))
print(len(a.encode('gbk')))
结果为

10
26
18
原因:len () 函数不区分中英文和数字,所有字符均按一个字节计算;encode () 方法计算实际占用字节数,默认 UTF-8 (汉字占三字节),若选择 gbk (汉字 2 字节)。

# 字符串切片

string[start : end : step]
注意 end 不包括在内哦~

1
2
3
 
a = '20级人工智能自动化'
print(a[1:7:2])
结果为

0 人智

# 分割合并字符串

listname = str,split(sep, maxsplit)
sep 参数默认为 None,级所有空字符
maxsplit 表示分割次数
分割字符串是把字符串分割成列表
合并是把列表合并成字符串
对字符串的操作方法都不会改变原来字符串的值

1
2
3
 
a = '山东大学,简称 山大 >>> www.sdu.edu.cn'
print(a.split(' ', 2))
结果为

[‘山东大学,简称’,‘山大’,’>>> www.sdu.edu.cn’]

strnew = string.join(iterable)
iterable 为可迭代对象
string 为合并时的分隔符

1
2
3
4
 
a = ['a','b','c']
str_friend = ' @'.join(a)
print(str_friend)
结果为

[‘山东大学,简称’,‘山大’,’>>> www.sdu.edu.cn’]

# 字符串的检索 count () 方法

str.count(sub, (start), (end))
用于检索指定字符串在另一个字符串中出现的次数,若不存在返回 0

1
2
3
 
a = 'how do you do'
print(a.count('o',1,5))
结果为

1

# 字符串的检索 find () 方法

str.find(sub, (start), (end))
用于检索是否包含指定的字符串,若不存在返回 - 1,否则返回首次出现该字符串的索引

# 字符串的检索 index () 方法

str.index(sub, (start), (end))
同 find () 方法,但是若不存在则会抛出异常(那不就没用吗

# 字符串的检索 startswith () 方法 和 endswith () 方法

用于检索字符串是否以指定字符串开头或者结尾,返回 True 或者 False。

# 字母大小写转换

strnew = string.lower()
strnew = string.upper()

# 去除字符串左右两侧的空格和特殊字符

str.strip([chars])
不加任何东西默认为空格、制表符、回车符、换行符。
左侧右侧可以分别用 lstrip 和 rstrip

# 格式化字符串

1
2
3
4
5
6
 
template = '编号:%09d 公司名称:%s'
context1 = (7,'百度')
context2 = (8,'淘宝')
print(template%context1)
print(template%context2)
结果为

编号:000000007 公司名称:百度
编号:000000008 公司名称:淘宝

1
2
 
print("{server}{1}:{0}".format(8888,'192.168.1.100',server='Web Server Info :'))
结果为

Web Server Info :192.168.1.100:8888

1
2
3
4
 
print("{0}*{1}={2:0>2}".format(3,2,2*3)
print("{:*^30}".format('centered'))
print("{:.3f}".format(3.14159))
结果为

3*2=06
centered
3.142

# 正则表达式

# cmd 的通配符

文件名中可以用 * 和?

  • "*" 可与任意一串字符匹配
  • "?" 可与任何一个实际字符匹配

# 正则表达式

  • 是一种用来匹配字符串的武器,是用来简洁表达一组字符串的表达式。
# 行定位符
1
2
 
^[0-9]+abc$

^ 表示匹配输入字符串的开始位置。
$ 表示匹配输入字符串的结束位置,这里意思是匹配以 abc 结尾的字符串。
+ 表示匹配一个或多个对象,这里的对象是 [0-9],即匹配一个或多个 “单个数字”。

# 元字符
元字符 作用
. 匹配除换行符以外的任意字符
\w 匹配汉字字母数字下划线
\W 匹配 \w 以外的字符
\s 匹配任意空白符
\b 匹配单词的开始或者结束
\d 匹配数字
# 限定字符
限定字符 作用
? 匹配零或一次对象
+ 匹配一或多次对象
* 匹配零或多次对象
‘{n}’ 匹配 n 次对象
‘{n,}’ 匹配至少 n 次对象
‘{n,m}’ 匹配 n 到 m 次对象
  • 备注:匹配特殊字符类似’-‘时,要用’' 转义,比如匹配 010-12345 则是 \d {3}-\d
# 字符类

若要做更精确的匹配,可用 [] 表示范围

1
2
 
[a-zA-Z\_][0-9a-zA-Z\_]*

该式子可以匹配由字母或下划线开头,后接任意个由一个数字、字母或者下划线组成的字符串,也就是 Python 合法的变量;

# 排除字符
1
2
 
[^a-zA-Z]

该式子表示匹配一个不是字母的字符

# 选择字符

用’|' 表示或者,比如身份证号码长度为 15 位数字或者 18 位,其中第十八个可能为数字或者 X
则匹配身份证的表达式为:

1
2
 
(^\d{15}$)|(^\d{18}$)|(^\d{17})(\d|X|x)$
  • 注意,这里的 ^ 表示匹配输入字符串的开始位置,放在 [] 里面才表示排除字符。
# 转义字符

转义字符 () 可以将特殊字符变为普通的字符
比如。表示匹配一个任意字符,. 就可以匹配 IP 地址了。

# 分组

小括号的作用有两个:

  • 改变限定字符的作用范围,比如 (a|b) c 和 a|bc 的区别,一个是匹配 ac 或 bc,一个是匹配 a 或 bc。
  • 分组,也就是子表达式,比如 (.0-9){3} 表示对分组 (.0-9) 进行重复操作。
# Python 中正则表达式的语法

在 python 中使用正则表达式的时候,是将其作为模式字符串使用的,意思就是,匹配一个字母的正则表达式是 [a-zA-Z],但在 python 里面要写成字符串形式,即写成’[a-zA-Z]’
匹配字母 m 开头的单词的正则表达式是 \bm\w*\b, 但是不能写成’\bm\w*\b’,因为 \ 需要转义,可以写成以下两个形式:

1
2
3
 
'\\bm\\w*\\b'
r'\bm\w*\b'

注意区分以下正则表达式:

  • (\s*) 表示匹配任意个空白符
  • [\s*] 表示匹配空白符或者 *

# 使用 re 模块实现正则表达式操作

(大概不考吧大概不考吧)