5. 容器类型
5.1 通用操作
5.1.1 数学运算符
运算符 | 说明 |
+ | 用于拼接两个容器 |
+= | 用原容器与右侧容器拼接,并重新绑定变量 |
* | 重复生成容器元素 |
*= | 用原容器生成重复元素, 并重新绑定变量 |
< <= > >= == != | 依次比较两个容器中元素,一但不同则返回比较结果。 |
# 1. 拼接2个容器元素
name = "悟空"
name += "八戒"
print(name) # 悟空八戒
# 2. 容器元素重复
name = "唐僧"
name *= 2
print(name) # 唐僧唐僧
# 3. 比较运算:依次比较两个容器中元素,一但不同则返回比较结果。
print("悟空" > "唐僧")
5.1.2 成员运算符
(1) 语法:
数据 in 序列
数据 not in 序列
(2) 作用:
如果在指定的序列中找到值,返回bool类型。
# 4. 成员运算
# True
print("悟空" in "我是齐天大圣孙悟空")
print("圣孙" in "我是齐天大圣孙悟空")
# False
print("齐圣" in "我是齐天大圣孙悟空")
print("圣大" in "我是齐天大圣孙悟空")
5.1.3 索引index
(1) 作用:定位单个容器元素。
(2) 语法:容器[整数]
(3) 说明:
正向索引:从0开始,第二个索引为1,最后一个为len(s)-1。
反向索引:从-1开始,-1代表最后一个,-2代表倒数第二个,以此类推,第一个是-len(s)。
message = "我是花果山齐天大圣"
print(message[2]) # 花
print(message[-2]) # 大
print(len(message)) # 9
# 注意:索引不能越界IndexError
# print(message[99])
# print(message[-99])
5.1.4 切片slice
(1) 作用:
定位多个容器元素。
(2) 语法:
容器[开始索引:结束索引:步长]
(3) 说明:
结束索引不包含该位置元素
步长是切片每次获取完当前元素后移动的偏移量
开始、结束和步长都可以省略
message = "我是花果山齐天大圣"
print(message[2:5:1]) # 花果山
print(message[1: 5]) # 是花果山
print(message[2:-4]) # 花果山
print(message[:-4]) # 我是花果山
print(message[:]) # 我是花果山齐天大圣
print(message[-3:]) # 天大圣
print(message[:2]) # 我是
print(message[-2:]) # 大圣
print(message[-2: 3:-1]) # 大天齐山
print(message[1: 1]) # 空
print(message[2: 5:-1]) # 空
# 特殊:翻转
print(message[::-1]) # 圣大天齐山果花是我
5.1.5 内建函数
(1) len(x) 返回序列的长度
(2) max(x) 返回序列的最大值元素
(3) min(x) 返回序列的最小值元素
(4) sum(x) 返回序列中所有元素的和(元素必须是数值类型)
5.2 字符串 str
5.2.1 定义
由一系列字符组成的不可变序列容器,存储的是字符的编码值。
5.2.2 编码
5.2.2.1基础知识
(1) 字节byte:计算机最小存储单位,等于8 位bit.
(2) 字符:单个的数字,文字与符号。
(3) 字符集(码表):存储字符与二进制序列的对应关系。
(4) 编码:将字符转换为对应的二进制序列的过程。
(5) 解码:将二进制序列转换为对应的字符的过程。
5.2.2.2 编码方式
(1) ASCII编码:包含英文、数字等字符,每个字符1个字节。
(2) GBK编码:兼容ASCII编码,包含21003个中文;英文1个字节,汉字2个字节。
(3) Unicode字符集:国际统一编码,旧字符集每个字符2字节,新字符集4字节。
(4) UTF-8编码:Unicode的存储与传输方式,英文1字节,中文3字节。
5.2.2.1 相关函数
(1) ord(字符串):返回该字符串的Unicode码。
(2) chr(整数):返回该整数对应的字符串。
# 文字 --> 数字
number = ord("我")
print(number) # 25105
# 数字 --> 文字
char = chr(25105)
print(char) # 我
5.2.3 字面值
5.2.3.1 单引和双引号的区别
(1) 单引号内的双引号不算结束符
(2) 双引号内的单引号不算结束符
5.2.3.2 三引号作用
(1) 换行会自动转换为换行符\n
(2)三引号内可以包含单引号和双引号
(3) 作为文档字符串
5.2.3.3 转义字符
(1) 定义:改变字符的原始含义。
(2) 语法:
\' \" \n \\ \t
(3) 原始字符串:取消转义。
a = r"C:\newfile\test.py"
5.2.3.4 字符串格式化
(1) 定义:生成一定格式的字符串。
(2) 语法:字符串%(变量)
"我的名字是%s,年龄是%s" % (name)
(3) 类型码:
%s 字符串 %d整数 %f 浮点数
print("%.2d:%.2d"%(2,3)) # 02:03
print("治愈比例为%d%%" % 5) # 治愈比例为5%
print("价格%.2f元" % (5 / 3)) # 价格1.67元
练习:根据下列文字,提取变量,使用字符串格式化打印信息
湖北确诊67802人,治愈63326人,治愈率0.99
70秒是01分零10秒
5.3 列表 list
5.3.1 定义
由一系列变量组成的可变序列容器。
5.3.2 基础操作
(1) 创建列表:
列表名 = []
列表名 = list(可迭代对象)
(2) 添加元素:
列表名.append(元素)
列表.insert(索引,元素)
(3) 定位元素:
列表名[索引] = 元素
变量 = 列表名[索引]
变量 = 列表名[切片] # 赋值给变量的是切片所创建的新列表
列表名[切片] = 容器 # 右侧必须是可迭代对象,左侧切片没有创建新列表。
(4) 遍历:
正向:
for 变量名 in 列表名:
变量名就是元素
反向:
for 索引名 in range(len(列表名)-1,-1,-1):
列表名[索引名]就是元素
(5) 删除元素:
列表名.remove(元素)
del 列表名[索引或切片]
# 1. 创建
# 写法1:列表名 = [数据1,数据2]
# 姓名列表
list_names = ["悟空", "唐三藏", "八戒", "沙僧"]
# 年龄列表
list_ages = [26, 23, 25, 16]
# 写法2:列表名 = list(可迭代对象)
list_name = list("孙悟空")
print(list_name) # ['孙', '悟', '空']
# 2. 添加
# -- 追加:列表名.append(数据)
list_names.append("小白龙")
# -- 插入: 列表名.insert(索引,数据)
list_names.insert(2, "哪吒")
print(list_names) # ['悟空', '唐三藏', '哪吒', '八戒', '沙僧', '小白龙']
# 3. 定位
# -- 索引:容器名[整数]
# -- 读取
element = list_names[-1]
print(element) # 小白龙
# -- 修改
list_names[-1] = "二郎神"
print(list_names) # ['悟空', '唐三藏', '哪吒', '八戒', '沙僧', '二郎神']
# -- 切片:容器名[整数:整数:整数]
# -- 通过切片读取,创建新列表(拷贝)
names = list_names[:3]
print(names) # ['悟空', '唐三藏', '哪吒']
# -- 通过切片修改,遍历右侧数据,依次存入左侧.
list_names[:3] = ["空空", "唐唐", "猪猪"]
# list_names[:3] = 100 # 因为100不能被for
list_names[:3] = "孙悟空"
print(list_names) # ['孙', '悟', '空', '八戒', '沙僧', '二郎神']
# 4. 遍历:操作容器每个元素
# -- 方式1: for 元素 in 容器
# 适用性:从头到尾依次读取
for name in list_names:
print(name)
# -- 方式2:for 索引 in range(开始,结束,间隔):
# 适用性:非从头到尾依次读取
# len(list_names) - 1 是 最大索引(总数-1)
# -1 索引可以去到0
# -1 倒序
# 功能:倒序
for i in range(len(list_names) - 1, -1, -1):
print(list_names[i])
# 功能:修改
for i in range(len(list_names)):
# 文字长度是3的修改为None
if len(list_names[i]) == 3:
list_names[i] = None
print(list_names) # ['孙', '悟', '空', '八戒', '沙僧', None]
# 5. 删除
# -- 方式1:根据元素删除 列表名.remove(元素)
list_names.remove("八戒")
# -- 方式2:根据定位删除 del 容器名[索引或者切片]
del list_names[0]
del list_names[-2:]
print(list_names) # ['悟', '空']
5.3.3 深拷贝和浅拷贝
浅拷贝:复制过程中,只复制一层变量,不会复制深层变量绑定的对象的复制过程。
深拷贝:复制整个依懒的变量。
练习1:画出下列代码内存图
list01 = ["北京", "上海"]
list02 = list01
list01[0] = "广东"
list03 = list01[:]
list03[-1] = "深圳"
print(list01)#?
练习2:画出下列内存图
list01 = ["北京", "上海", "深圳"]
list02 = list01
list01.insert(0,"天津")
del list01[1]
print(list02)# ?
练习3:画出下列内存图
import copy
list01 = ["北京",["上海","深圳"]]
list02 = list01
list03 = list01[:]
list04 = copy.deepcopy(list01)
list04[0] = "北京04"
list04[1][1] = "深圳04"
print(list01) # ?
list03[0] = "北京03"
list03[1][1] = "深圳03"
print(list01) # ?
list02[0] = "北京02"
list02[1][1] = "深圳02"
print(list01) # ?
5.3.4 列表与字符串转
(1) 列表转换为字符串:
result = “连接符”.join(列表)
list01 = ["a", "b", "c"]
result = "-".join(list01)
print(result)
(2) 字符串转换为列表:
列表 = “a-b-c-d”.split(“分隔符”)
# 使用一个字符串存储多个信息
list_result = "唐僧,孙悟空,八戒".split(",")
print(list_result)
5.3.5 列表推导式
(1) 定义:
使用简易方法,将可迭代对象转换为列表。
(2) 语法:
变量 = [表达式 for 变量 in 可迭代对象]
变量 = [表达式 for 变量 in 可迭代对象 if 条件]
(3) 说明:
如果if真值表达式的布尔值为False,则可迭代对象生成的数据将被丢弃。
list01 = [9, 15, 65, 6, 78, 89]
# 需求:在list01中挑出能被3整除的数字存入list02
# list02 = []
# for item in list01:
# if item % 3 == 0:
# list02.append(item)
list02 = [item for item in list01 if item % 3 == 0]
print(list02)
# 需求:在list01中所有数字的个位存储list03
# list03 = []
# for item in list01:
# list03.append(item % 10)
list03 = [item % 10 for item in list01]
print(list03)
练习:
生成10–30之间能被3或者5整除的数字
[10, 12, 15, 18, 20, 21, 24, 25, 27]
生成5 – 20之间的数字平方
[25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361]
(4) 列表推导式嵌套
变量 = [表达式 for 变量1 in 可迭代对象1 for 变量2 in可迭代对象2]
#result = []
#for r in ["a", "b", "c"]:
# for c in ["A", "B", "C"]:
# result.append(r + c)
result = [r + c for r in list01 for c in list02]
5.4 元组 tuple
5.4.1 定义
(1) 由一系列变量组成的不可变序列容器。
(2) 不可变是指一但创建,不可以再添加/删除/修改元素。
5.4.2 基础操作
(1) 创建空元组:
元组名 = ()
元组名 = tuple()
(2) 创建非空元组:
元组名 = (20,)
元组名 = (1, 2, 3)
元组名 = 100,200,300
元组名 = tuple(可迭代对象)
(3) 获取元素:
变量 = 元组名[索引]
变量 = 元组名[切片] # 赋值给变量的是切片所创建的新列表
(4) 遍历元组:
正向:
for 变量名 in 列表名:
变量名就是元素
反向:
for 索引名 in range(len(列表名)-1,-1,-1):
元组名[索引名]就是元素
5.4.3 作用
(1) 元组与列表都可以存储一系列变量,由于列表会预留内存空间,所以可以增加元素。
(2) 元组会按需分配内存,所以如果变量数量固定,建议使用元组,因为占用空间更小。
(3) 应用:
变量交换的本质就是创建元组:x, y = (y, x )
格式化字符串的本质就是创建元祖:“姓名:%s, 年龄:%d” % (“tarena”, 15)
5.5 字典 dict
5.5.1 定义
(1) 由一系列键值对组成的可变散列容器。
(2) 散列:对键进行哈希运算,确定在内存中的存储位置,每条数据存储无先后顺序。
(3) 键必须惟一且不可变(字符串/数字/元组),值没有限制。
5.5.2 基础操作
(1) 创建字典:
字典名 = {键1:值1,键2:值2}
字典名 = dict (可迭代对象)
(2) 添加/修改元素:
语法:
字典名[键] = 数据
说明:
键不存在,创建记录。
键存在,修改值。
(3) 获取元素:
变量 = 字典名[键] # 没有键则错误
(4) 遍历字典:
for 键名 in 字典名:
字典名[键名]
for 键名,值名 in 字典名.items():
语句
(5) 删除元素:
del 字典名[键]
5.5.3 字典推导式
(1) 定义:
使用简易方法,将可迭代对象转换为字典。
(2) 语法:
{键:值 for 变量 in 可迭代对象}
{键:值 for 变量 in 可迭代对象 if 条件}
5.6 集合 set
5.6.1 定义
(1) 由一系列不重复的不可变类型变量(元组/数/字符串)组成的可变散列容器。
(2) 相当于只有键没有值的字典(键则是集合的数据)。
5.6.2 基础操作
(1) 创建空集合:
集合名 = set()
集合名 = set(可迭代对象)
(2) 创建具有默认值集合:
集合名 = {1, 2, 3}
集合名 = set(可迭代对象)
(3) 添加元素:
集合名.add(元素)
(4) 删除元素:
集合名.discard(元素)
# 1. 创建
# -- 集合名 = {元素1,元素2,元素3}
set01 = {"悟空", "唐僧", "八戒"}
list01 = ["唐僧", "悟空", "唐僧", "八戒", "唐僧"]
# -- 集合名 = set(可迭代对象)
set02 = set(list01)
print(set02) # {'八戒', '悟空', '唐僧'}
# 2. 添加:集合名.add(元素)
set02.add("小白龙")
print(set02) # {'悟空', '八戒', '小白龙', '唐僧'}
# 定位
#(因为无序不能使用索引切片)
#(因为不是键值对不能使用键查找键)
# 3. 遍历
for item in set01:
print(item)
# 4. 删除
if "悟空1" in set01:
set01.remove("悟空1")
5.6.3 运算
(1) 交集&:返回共同元素。
s1 = {1, 2, 3}
s2 = {2, 3, 4}
s3 = s1 & s2 # {2, 3}
(2) 并集:返回不重复元素
s1 = {1, 2, 3}
s2 = {2, 3, 4}
s3 = s1 | s2 # {1, 2, 3, 4}
(3) 补集-:返回只属于其中之一的元素
s1 = {1, 2, 3}
s2 = {2, 3, 4}
s1 - s2 # {1} 属于s1但不属于s2
(4) 补集^:返回不同的的元素
s1 = {1, 2, 3}
s2 = {2, 3, 4}
s3 = s1 ^ s2 # {1, 4} 等同于(s1-s2 | s2-s1)
(5) 子集<:判断一个集合的所有元素是否完全在另一个集合中
(6) 超集>:判断一个集合是否具有另一个集合的所有元素
s1 = {1, 2, 3}
s2 = {2, 3}
s2 < s1 # True
s1 > s2 # True
(7) 相同或不同== !=:判断集合中的所有元素是否和另一个集合相同。
s1 = {1, 2, 3}
s2 = {3, 2, 1}
s1 == s2 # True
s1 != s2 # False
子集或相同,超集或相同 <= >=
练习:一家公司有如下岗位:
“经理”:“曹操”,“刘备”,“孙权”
“技术” :“曹操”,“刘备”,“张飞”,“关羽”
- 定义数据结构,存储以上信息.
- 是经理也是技术的都有谁?
- 是经理不是技术的都有谁?
- 不是经理是技术的都有谁?
- 身兼一职的都有谁?
- 公司总共有多少人数?
5.6.4 集合推导式
(1) 定义:
使用简易方法,将可迭代对象转换为集合。
(2) 语法:
{表达式 for 变量 in 可迭代对象}
{表达式 for 变量 in 可迭代对象 if 条件}
6 函数 function
6.1 pycharm快捷键
Ctrl + P 参数信息(在方法中调用参数)
Ctrl + Q 快速查看文档
6.2 定义
(1) 用于封装一个特定的功能,表示一个功能或者行为。
(2) 函数是可以重复执行的语句块, 可以重复调用。
6.3 作用
提高代码的可重用性和可维护性(代码层次结构更清晰)。
6.4 基础语法
6.4.1 定义函数
(1) 语法:
def 函数名(形式参数):
函数体
(2) 说明:
def 关键字:全称是define,意为”定义”。
函数名:对函数体中语句的描述,规则与变量名相同。
形式参数:函数定义者要求调用者提供的信息。
函数体:完成该功能的语句。
(3) 函数的第一行语句建议使用文档字符串描述函数的功能与参数。
# 形式参数:表面的不具体的数据
def attack(count):
"""
攻击
:param count:次数
"""
for __ in range(count):
print("直拳")
print("摆拳")
print("勾拳")```
#### 6.4.2 调用函数
(1) 语法:函数名(实际参数)
(2) 说明:根据形参传递内容。
#### 6.4.3 返回值
(1) 定义:
函数定义者告诉调用者的结果。
(2) 语法:
return 数据
(3) 说明:
return后没有语句,相当于返回 None。
函数体没有return,相当于返回None。
```python
def func01():
print("func01执行了")
return 100
# 1. 调用者,可以接收也可以不接收返回值
func01()
res = func01()
print(res)
# 2.在Python语言中,
# 函数没有return或return后面没有数据,
# 都相当于return None
def func02():
print("func02执行了")
return
res = func02()
print(res) # None
# 3.return可以退出函数
def func03():
print("func03执行了")
return
print("func03又执行了")
func03()
# 4. return 可以退出多层循环嵌套
def func04():
while True:
while True:
while True:
# break 只能退出一层循环
print("循环体")
return
func04()
6.5 可变/不可变类型在传参时的区别
不可变类型参数 | 可变类型参数 |
数值型(整数,浮点数) | 列表 list |
布尔值bool | 字典 dict |
None 空值 | 集合 set |
字符串str | |
元组tuple |
传参说明:
不可变类型的数据传参时,函数内部不会改变原数据的值。
可变类型的数据传参时,函数内部可以改变原数据。
6.6 函数参数
6.7 作用域LEGB
6.7.1 定义
变量起作用的范围。
6.7.2 分类
(1) Local局部作用域:函数内部。
(2) Enclosing 外部嵌套作用域 :函数嵌套。
(3) Global全局作用域:模块(.py文件)内部。
(4) Builtin内置模块作用域:builtins.py文件。
6.7.3 变量名的查找规则
(1) 由内到外:L -> E -> G -> B
(2) 在访问变量时,先查找本地变量,然后是包裹此函数外部的函数内部的变量,之后是全局变量,最后是内置变量。
6.7.4 局部变量
(1) 定义在函数内部的变量(形参也是局部变量)
(2) 只能在函数内部使用
(3) 调用函数时才被创建,函数结束后自动销毁
6.7.5 全局变量
(1) 定义在函数外部,模块内部的变量。
(2) 在整个模块(py文件)范围内访问(但函数内不能将其直接赋值)。
6.7.6 global 语句
(1) 作用:
在函数内部修改全局变量。
在函数内部定义全局变量(全局声明)。
(2) 语法:
global 变量1, 变量2, …
(3) 说明
在函数内直接为全局变量赋值,视为创建新的局部变量。
不能先声明局部的变量,再用global声明为全局变量。
6.7.7 nonlocal 语句
(1) 作用:
在内层函数修改外层嵌套函数内的变量
(2) 语法
nonlocal 变量名1,变量名2, …
(3) 说明
在被嵌套的内函数中进行使用
# 2. 全局作用域:文件内部
# 全局变量:在全部作用域内创建的变量
# 适用范围:整个文件
data02 = 20
data03 = [30]
def func01():
# 1. 局部作用域:函数内部
# 局部变量:在局部作用域内创建的变量
# 适用范围:一个函数
data01 = 10
print(data01)
print(data02)
def func02():
# print(data01) # 不能访问其他函数局部变量
print(data02) # 读取全局变量
def func03():
# 在局部作用域中不能修改全局变量
# data02 = 200
# 必须通过global语句声明
global data02
data02 = 200
def func04():
# 没有修改全局变量
# 在修改全局变量指向的列表
# 所以不需要通过global语句声明
data03[0] = 300
func01()
func02()
func03()
func04()
print(data02) # 200
print(data03) # [300]
Python核心:思维导图笔记