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

子集或相同,超集或相同 <= >=
练习:一家公司有如下岗位:
“经理”:“曹操”,“刘备”,“孙权”
“技术” :“曹操”,“刘备”,“张飞”,“关羽”

  1. 定义数据结构,存储以上信息.
  2. 是经理也是技术的都有谁?
  3. 是经理不是技术的都有谁?
  4. 不是经理是技术的都有谁?
  5. 身兼一职的都有谁?
  6. 公司总共有多少人数?

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 函数参数

sympy Function 语法_python

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核心:思维导图笔记

sympy Function 语法_开发语言_02