2. Python基础
2.1 输入语句
语法:变量 = input("提示信息")
作用:= 是等于赋值的意思。变量=input顺序不能变意思是右边给左边
输入函数功能input,从终端中获取输入的信息,存到程序(变量)运行代码之后可自定义输入目标数据,返回结果为str(字符串)类型。
实例(1)简单用法:直接提示输出,可用于调试学习input函数。直接赋值得到字符串。
(2)与int函数结合使用,为变量赋整数值。
(3)与float函数结合使用,为变量赋浮点数值。
例子:calss_01 = input("请输入班级")
注意:对于input()函数来说,不管我们输入的回答是什么,不管输入的是整数1234,还是字符串,input()函数的输入值(搜集到的回答),永远会被【强制性】地转换为【字符串】类型。返回类型必定为str。
2.2 输出语句
语法:print = (""),file:类文件对象(stream);默认当前是sys.stdout
sep:在值之间插⼊的字符串,默认为空格。 end:在最后⼀个值后附加的字符串,默认为换⾏符。 flush:是否强制刷新流。 sep可选关键字参数 sep参数可以在值之间插⼊字符串,默认值为空格。 print(’1‘,’2‘,’3‘,’4‘,sep = ”插⼊“) 输出结果: 1插⼊2插⼊3插⼊4 file可选关键字参数 file参数默认值为sys.stdout,代表系统标准输出,即屏幕。我们可以通过改变该参数使print()函数输出到特定的⽂件中。例: f = open(r”F:\text.txt“,”w“) # 打开⽂件,以便写如 print(’test‘,file = f) # 输出到⽂件 f.close() # 关闭⽂件 运⾏后,可以看到test输出到text.txt⽂件中。 end可选关键字参数 end参数默认为”\n“(换⾏符),如果想在print()函数输出之后输出别的字符串,可以重设end参数。 print(’1‘,’2‘,end = ”最后“) 输出结果: 运⾏后,我们可以看到,print()函数输出之后不会换⾏,且在最后⼀个值后⾯附加了“最后”。 5、flush可选关键字参数 flush参数⽤于控制输出缓存,⼀般为了可以获得较好的性能,保持为False即可
作用: print打印功能显示输出将括号中内容显示到终端
实例:输出单个值,输出多个值
例子:print("你好!")
2.3 标识符与关键字
语法:Python 标识符在 Python 里,标识符由字母、数字、下划线组成。在 Python 中,所有标识符可以包括英文、数字以及下划线(_),但不能以数字开头。Python 中的标识符是区分大小写的。以下划线开头的标识符是有特殊意义的
作用:标识符是编程时使用的名字,主要是给变量、函数、语句块等命名。
例子:name_01=input("请输入班级")中name_01作为一个标识符当变量使用
关键字:Python关键字也叫保留字,是预先保留的标识符,每个关键字都有特殊的含义,不能用作变量名、函数名或任何其他标识符 Python关键字如下 实例:if、elif、else、for、while、pass、assert、del、from、global、with、yield、not、and、or、True、False、None、class、def、try、except、finally、raise。
2.4 注释方法
作用:注释的作用是给代码提供解释和说明,提高代码的可读性。Python中的注释有两种形式:单行注释和多行注释。
2.4.1 单行注释
语法:以“#”开头,后面是注释内容。
作用:它的作用是在代码行的末尾添加说明或解释,以帮助其他开发者理解代码的功能和目的。单行注释可以单独占一行,也可以放在代码行的末尾。
例子:python#这是一个单行注释
print("Hello, World!") # 这是打印语句后面的注释
2.4.2 多行注释
语法:用三个引号(单引号或双引号)括起来的注释内容。
作用:它的作用是在多行之间添加说明或解释,以帮助其他开发者更好地理解代码。多行注释通常用于解释复杂的代码段或函数。
例子:python """ 这是一个多行注释的示例。 这里可以写很多行注释内容, 以帮助其他开发者理解代码的功能和逻辑。 """
print("Hello, World!")
2.5 常量与变量
在Python中,变量和常量都是用来存储数据的基本单元。 常量作用:是指在程序运行期间其值不会发生改变的量。
语法:在Python中,常量通常使用全大写字母来表示,以区别于变量。
例子:python PI = 3.14159 MAX_NUM = 100 变量作用:在程序运行期间其值可以发生改变的量。
语法在Python中,变量使用小写字母或下划线来表示。
例子:python age = 25 name = "John" 变量和常量的命名规则如下:
变量名和常量名必须以字母(A-Za-z)或下划线(_)开头。 变量名和常量名可以包含字母、数字和下划线,但不能用数字开头。 变量名和常量名是区分大小写的。 在Python中,变量的赋值非常灵活,可以将一个值赋给一个变量,也可以将一个变量的值赋给另一个变量。例如:
python x = 10 # 将整数值10赋给变量x y = x # 将变量x的值赋给变量y,此时y的值也是10 z = "hello" # 将字符串"hello"赋给变量z 注意,在Python中,等号(=)是赋值运算符,而不是比较运算符。因此,不能使用等号来判断两个值是否相等,而应该使用双等号(==)来进行比较。例如:
python x = 10 y = 20 if x == y: # 判断x和y是否相等 print("x and y are equal")
2.5.1 常量与变量的区别
修改性:常量是不可修改的,而变量是可修改的。 值的变化性:常量在程序运行期间是不变的,其值一旦被定义就不能再被改变。而变量在程序运行期间可以变化,可以随时被赋予新的值。 定义的方式:常量通常使用全大写字母来表示,而变量使用小写字母或下划线来表示 作用域:常量具有全局作用域,在程序的任何地方都可以访问。而变量则具有局部作用域,只有在声明它的代码块内才能访问。 使用场景:常量用于存储不会改变的值,如圆周率或者一些预定义的常量值。而变量则用于存储程序中可能会变化的值。
2.5.1 变量的定义与赋值
变量是用于存储数据的一种手段。它是存储值的容器,以便在程序中引用和操作这些值。
变量的定义通常包括变量名和数据类型。变量名是用于标识变量的名称,数据类型则决定了变量可以存储的数据种类。
在定义变量之后,需要将值赋给变量,这个过程称为赋值。赋值操作将一个值存储到变量中,以便在程序中使用。
以下是Python中变量定义和赋值的示例:
# 定义一个整数类型的变量 age = 30 # 定义一个字符串类型的变量 name = "John" # 定义一个浮点数类型的变量 price = 19.99
在这个例子中,我们定义了三个变量:age
、name
和price
。age
是一个整数类型的变量,可以存储整数值;name
是一个字符串类型的变量,可以存储文本数据;price
是一个浮点数类型的变量,可以存储带有小数点的数值。
然后,我们使用赋值操作将这些值分别赋给了这三个变量:age = 30
、name = "John"
和price = 19.99
。这样,我们就可以在程序中使用这些变量及其对应的值进行操作和计算了。
2.6 数据类型简介
2.6.1 数据类型
2.6.1.1 Number类型(数字)
作用:数字类型通常用于表示数值或数字
2.6.1.1.1 int(整型)
作用:整数类型,用于表示正整数或负整数。
2.6.1.1.2 float(浮点型)
作用:浮点数类型,用于表示带有小数点的数值。
2.6.1.1.3 bool(布尔型)
作用:比较运算符 > < >= <= ==(等于) !=(不等于)结果是bool类型;逻辑运算符 与 或 非 判断倆个bool值关系。
语法:bool类型true(真,对的) false(假,错的) 取值
命题:带有判断性的陈述句
例如:1 > 2 -----> false
2.6.1.1.4 complex(复数)
作用:由实部和虚部组成数字,虚部是以j或j结尾的。
2.6.1.2 string(字符串型)
作用:用于存储和处理文本数据。字符串是由零个或多个字符组成的序列,每个字符都有一个对应的Unicode码点。
2.6.1.2.1 字符串的定义
作用:字符串是由零个或多个字符组成的序列。字符串的字面值可以使用单引号、双引号或三引号定义,
例子:如:
s1 = 'Hello' s2 = "World" s3 = '''This is a multiline string.'''
2.6.1.2.2 字符串的拼接
作用:可以使用加号+
或字符串方法join()
来拼接字符串。
例子:使用加号+
拼接字符串:
str1 = 'Hello' str2 = ' World' result = str1 + str2 print(result) # 输出 'Hello World'
使用字符串方法join()
拼接字符串:
str1 = 'Hello' str2 = ' World' result = ''.join([str1, str2]) print(result) # 输出 'Hello World'
需要注意的是,如果要拼接的字符串中包含数字、布尔值或其他非字符串类型,需要先将其转换为字符串类型,
2.6.1.2.3 字符串的格式化
作用:主要是将变量(对象)的值填充到字符串中,并在字符串中解析Python表达式,对字符串进行格式化显示(如左对齐、右对齐、居中对齐,保留数字有效位数等)。这使得我们能够更便捷地将字符串进行拼接成一串新的字符串。
Python提供了多种字符串格式化的方法,以下是其中几种:
-
使用%符号进行格式化:
name = 'Alice' age = 25 print('My name is %s and I am %d years old.' % (name, age))
-
使用
format()
函数进行格式化:
name = 'Alice' age = 25 print('My name is {} and I am {} years old.'.format(name, age))
2.6.1.3 序列类型(后面会着重讲可以先了解有哪些)
作用:这些序列类型都可以进行索引、切片、连接等操作
在Python中,序列类型包括:
-
字符串(str):由零个或多个字符组成的有序字符序列。
-
列表(list):由任意数量和类型的对象组成的可变的有序集合。列表是可变的,意味着你可以在创建列表后更改、添加或删除其元素。
-
元组(tuple):与列表类似,元组也是由任意数量和类型的对象组成的可变的有序集合。但是,元组是不可变的,一旦创建就不能更改其元素。
2.6.2 数据类型查看
作用:数据类型的作用主要也是为了提高效率和规范性。
以使用type()
函数来查看一个对象的类型
x = 'Hello, world!' print(type(x)) # 输出 <class 'str'> y = [1, 2, 3, 4, 5] print(type(y)) # 输出 <class 'list'> z = (1, 2, 3) print(type(z)) # 输出 <class 'tuple'>
除此之外,你还可以使用dir()
函数查看一个对象的所有属性和方法,例如:
x = 'Hello, world!' print(dir(x))
2.6.3 数据类型的转换
作用:据类型的转换可以让我们的代码更灵活、易读和高效。当我们需要处理不同类型的数据时,合理地使用数据类型的转换可以让我们更好地理解和操作数据。
隐式类型转换(自动类型转换)
隐式类型转换,也称为自动类型转换,是指Python在处理表达式时自动进行的类型转换。例如,当一个数值与字符串进行运算时,Python会自动将数值转换为字符串,然后再进行运算。例如:
num = 5 str_num = "5" print(num + str_num) # 输出 '55'
在这个例子中,num
是一个整数,而str_num
是一个字符串。Python会自动将num
转换为字符串,然后与str_num
进行连接操作,得到结果 '55'。
显式类型转换(强制类型转换)
显式类型转换,也称为强制类型转换,是指程序员明确指定变量的类型。在Python中,可以使用内置的函数进行类型转换,如int()
, float()
, str()
, list()
, tuple()
等。例如:
num = 5.5 int_num = int(num) # 将浮点数转换为整数 print(int_num) # 输出 5
在这个例子中,我们使用int()
函数将浮点数num
转换为整数。注意,这里的转换可能会导致精度损失,因为浮点数的小数部分会被截断。
转换为字符串:str(数据)以此类推整型等等
转换成布尔:bool(数据)特殊
结果为false:bool(0) bool(0.0) bool(none)
()有数字都是true1,1.1
2.7 运算符
2.7.1 算术(数学)运算符
2.7.1.1 相加"+"
作用:返回操作数的总和。
语法:# 加法 x = 2 + 3 print(x) # 输出 5
2.7.1.2 相减"-"
返回两个数的差。
减法
x = 5 - 2 print(x) # 输出 3
2.7.1.3 相乘"*"
返回两个数的积。
乘法
x = 2 * 3 print(x) # 输出 6
2.7.1.4 相除"/"
返回两个数的商。
除法
x = 6 / 3 print(x) # 输出 2.0
2.7.1.5 相除取整"//"
返回两个数相除后的整数结果。
x = 7 // 3
print(x)输出2
2.7.1.6 相除取余"%"
,返回除法运算的余数。
取模(取余数) x = 7 % 3 print(x) # 输出 1
2.7.1.7 幂运算"**"
回第一个参数的第二个参数次方的结果。
例如,2 ** 3 返回8。
2.7.2 比较运算符
2.7.2.1 相等==
如果两个值相等,则返回True。
2.7.2.2 大于">"
如果左边的值大于右边的值,则返回True。
2.7.2.3 大于等于">="
如果左边的值大于或等于右边的值,则返回True。
2.7.2.4 小于"<"
果左边的值小于右边的值,则返回True。
2.7.2.5 小于等于"<="
如果左边的值小于或等于右边的值,则返回True。
2.7.2.6 否"!"
在Python中是一个逻辑非运算符。它可以将一个布尔值取反。如果原来的布尔值为True,则使用感叹号运算符后结果为False;如果原来的布尔值为False,则使用感叹号运算符后结果为True。
2.7.3 赋值运算符
-
=
: 赋值运算符,将右边的值赋给左边的变量。 -
+=
: 加等于运算符,等同于x = x + y
。 -
-=
:减等于运算符,等同于x = x - y
。 -
*=
: 乘等于运算符,等同于x = x * y
。 -
/=
:除等于运算符,等同于x = x / y
。 -
//=
:整除等于运算符,等同于x = x // y
。 -
%=
: 取模等于运算符,等同于x = x % y
。
3. 程序三大基本结构
3.1 顺序结构
语法:它是由一系列按顺序排列的语句组成的。每个语句都会被依次执行,没有任何跳转或条件判断。
作用:是按照一定的顺序执行操作,适用于简单的任务,其中每个操作都需要按顺序执行。顺序结构程序通常用于计算简单的数学表达式、执行基本的输入/输出操作等。
实例:
a = 5 b = 10 c = a + b print(c) 这个程序首先将5赋值给变量a,然后将10赋值给变量b,接着将a和b相加的结果赋值给变量c,最后打印出变量c的值。这个程序按照自上而下的顺序执行每个语句,没有任何分支或循环。
3.1.1 定义
顺序结构程序通常用于简单的任务,其中每个操作都需要按顺序执行。例如,计算一个简单的数学表达式就是一个典型的顺序结构程序。
3.1.2 练习
num1 = int(input("请输入第一个数字:"))
num2 = int(input("请输入第二个数字:"))
sum = num1 + num2
print("两个数字的和为:", sum)
num = int(input("请输入一个数字:"))
if num % 2 == 0:
print(num, "是偶数")
else:
print(num, "是奇数")
3.2 分支结构
3.2.1 单分支
语法:单分支结构通常使用if语句来实现。if语句根据某个条件是否为真来决定执行哪一段代码。
作用:单分支结构是一种基本的程序控制结构,它包括一个条件语句和两条执行路径。如果条件为真,执行第一条路径;否则执行第二条路径。
例子:if condition:
#do something if the condition is true
else:
#do something if the condition is false
其中,condition
是一个布尔表达式,如果它的值为真,就执行if语句下面的代码块;否则执行else语句下面的代码块。
单分支结构通常用于根据不同的条件执行不同的操作,例如根据用户输入的不同命令执行不同的操作,或者根据某个变量的不同值执行不同的操作。
3.2.2 双分支
作用:双分支结构是一种基本的程序控制结构,它包括两个条件语句和两条执行路径。第一个条件语句为真时执行第一条路径,否则执行第二个条件语句。如果第二个条件语句仍然为假,则执行第二条路径。
语法:双分支结构通常使用if-else语句来实现。if-else语句根据第一个条件是否为真来决定执行哪一段代码。如果第一个条件为假,则执行第二个条件语句。
在大多数编程语言中,if-else语句的语法如下:
if condition1: # do something if condition1 is true else if condition2: # do something if condition1 is false and condition2 is true else: # do something if both condition1 and condition2 are false
其中,condition1
和condition2
是布尔表达式,如果condition1
为真,就执行if语句下面的代码块;否则执行第一个else if语句下面的代码块。如果condition1
为假且condition2
为真,则执行第一个else if语句下面的代码块。如果condition1
和condition2
都为假,则执行第二个else语句下面的代码块。
双分支结构通常用于根据不同的条件执行不同的操作,例如根据用户输入的不同命令执行不同的操作,或者根据某个变量的不同值执行不同的操作。下面是一个例子:
score = int(input("请输入分数:")) if score >= 90: print("优秀") elif score >= 80: print("良好") elif score >= 60: print("及格") else: print("不及格")
这个例子根据用户输入的分数判断成绩等级,如果分数大于等于90分为优秀,如果分数在80分到89分之间为良好,如果分数在60分到79分之间为及格,否则为不及格。
3.2.3 多分支
作用:多分支结构的作用和意义在于能够根据多个条件执行不同的操作。它允许程序根据多个不同的条件进行判断和执行,增加了程序的灵活性和可读性。
语法:多分支结构通常使用多个if语句或switch语句来实现。每个条件语句都会检查一个特定的条件,如果该条件为真,则执行相应的代码块。如果所有条件都不满足,则执行默认的代码块(如果有的话)。
例子:
day = input("请输入星期几:") if day == "Monday": print("星期一") elif day == "Tuesday": print("星期二") elif day == "Wednesday": print("星期三") elif day == "Thursday": print("星期四") elif day == "Friday": print("星期五") elif day == "Saturday": print("星期六") elif day == "Sunday": print("星期日") else: print("无效的输入")
这个例子根据用户输入的星期几打印出相应的信息。如果输入的是有效的星期几,程序会打印出相应的信息;否则,程序会打印出“无效的输入”。
多分支结构可以用于各种场景,比如用户输入验证、条件语句处理、数据筛选等等。它可以增加程序的灵活性和可读性,使程序能够根据不同的条件执行不同的操作。
3.2.4 分支嵌套
语法:分支嵌套是指在一个条件语句内部嵌入另一个条件语句,即条件语句中嵌套条件语句。分支嵌套的作用和意义在于能够增加程序的复杂性和灵活性,以处理更复杂的条件判断和操作执行。
作用:通过分支嵌套,可以在一个条件语句中根据子条件的不同执行不同的代码块。这样可以将程序分解为更小的逻辑部分,提高代码的可读性和可维护性。同时,分支嵌套还可以实现程序的流程控制和条件判断的组合,以处理更为复杂的问题。
例子:
score = int(input("请输入分数:")) if score >= 90: grade = "优秀" elif score >= 80: if score >= 85: grade = "良好" else: grade = "及格" else: grade = "不及格" print("成绩等级为:", grade)
这个例子根据用户输入的分数判断成绩等级。首先根据总分数的范围判断成绩等级,然后再根据子条件判断具体的等级。如果输入的分数大于等于90分,成绩等级为“优秀”;如果输入的分数在80分到89分之间,则根据是否大于等于85分判断成绩等级为“良好”或“及格”;否则成绩等级为“不及格”。通过分支嵌套,可以实现更复杂的条件判断和操作执行。
3.3 循环结构
3.3.1 while循环
作用:while
循环是一种基本的控制流语句,它用于在满足特定条件的情况下反复执行一段代码。只要条件保持为真,循环就会持续执行。当条件变为假时,循环将停止执行。
while
循环的意义在于,它们使我们能够重复执行代码块,直到满足某个特定条件。这对于需要重复执行相同任务的情况非常有用,比如迭代、搜索、模拟等。
为了让语句执行后不停止。
死循环:循环条件永远满足。 #whlie true:
break 打破,停止。退出循环体
#关于对while的训练。 import random random_number = random.randint(1,100) count = 0 while count< 5: count += 1 number = int(input("请输入数字")) if number > random_number: print("大了") elif number < random_number: print("小了") else: print("输入正确输入所用次数"+str(count)+"次") break else: print("游戏结束")
练习关于while猜数字游戏。
import random random_number = random.randint(1,100)
这串代码的意思是在一到一百中随机生成一个数字
while True: import random random_number = random.randint(1,1000) print(random_number) if random_number == 457: break
这是一个随机生成数字,意思是死循环在1到1000中随机生成数字,直至生成到457这个数字则停止程序。
import random numbers = [427,429,425,308] # 这是你的数字列表 chosen_number = random.choice(numbers) # 从列表中随机选择一个数字 print(chosen_number) # 输出被选择的数字
number中输入特定的数字,进行随机选择。
while True: ji_jie = input("请输入季节") if ji_jie == "春天": print("1月2月3月") elif ji_jie == "夏天": print("4月5月6月") elif ji_jie == "秋天": print("7月8月9月") elif ji_jie == "冬天": print("10月11月12月") if input("输入e键退出") == "e": break
需求执行3次
count = 0 while count < 3 : count += 1 usd = int(input("请输入美元")) print(usd * 6.9)
循环设置计数器
练习:在控制台中获取月份,显示季度,或者提示月份错误
while True: month = int(input("请输入月份")) if month < 1 or month > 12 : print("月份错误") elif month <= 3: print("春天") elif month <= 6: print("夏天") elif month <= 9: print("秋天") elif month <= 12: print("冬天")
year = int(input("请输入年龄")) if year< 0 : print("打印错误") elif 2<= year<= 13: print("是一个婴儿") elif 13< year<= 20: print("是一个少年") elif 20< year<= 65: print("是一个成人") elif 65 < year <= 150: print("是一个老人") else: print("那是不可能")
while True: year = int(input("请输入年龄")) if year< 0 : print("打印错误") elif 2<= year<= 13: print("是一个婴儿") elif 13< year<= 20: print("是一个少年") elif 20< year<= 65: print("是一个成人") elif 65 < year <= 150: print("是一个老人") else: print("那是不可能")
begin = int (input("请输入开始值")) end = int(input("请输入结束值")) while begin < end-1 : begin += 1 print(begin)
4.3打印中间数据值
练习一张纸的高度是0.01毫米,计算对折多少次高度能够超过珠穆朗玛峰8844.43m
thickness = 0.01 /100 count = 0 while thickness < 8844.43 : count += 1 thickness *= 2 print(count)
count作为一个计数器,print为什么不缩进因为不在循环体内
练习猜数字游戏,游戏运行产生一个1—100之间的随机数,让玩家重复猜测知道玩家猜对为止。提示大了小了,猜对了。猜对了总共猜了多少次
准备一个产生随机数的公式 开头写一次
产生一个随机数
import random random_number = random.randint(1,100) count = 0 while True: count += 1 number = int(input("请输入数字")) if number > random_number: print("大了") elif number < random_number: print("小了") else: print("输入正确共猜"+str(count)+"次") break
猜数字2.0
最多猜三次,如果超过次数则游戏结束。
import random random_number = random.randint(1,100) count = 0 while count<3: count += 1 number = int(input("请输入数字")) if number > random_number: print("大了") elif number < random_number: print("小了") else: print("输入正确共猜"+str(count)+"次") break#这里的break、不会影响下面的else。或者来说这是退出循环体不会执行 else: print("游戏失败")
思路:前两行代码是对于1到100随机数的抽取,count是对于循环的次数进行限制。if对于number和random_number之间的大小进行判断。并进行提示,如果不满足大于或者小于则会显示正确并且插入猜对的次数,break结束循环。
如果三次的次数到了则会else进行输入游戏失败。
else语句可以省略while与else是一个语法。
练习根据成绩判断等级,如果录入的空字符串则退出程序。
如果成绩录入错误次数达到三次,则退出提示成绩错误过多
3.3.2 range语句
作用:range()
是Python中的一个内置函数,它用于生成一个整数序列,通常用于循环中。range()
函数可以接受1个、2个或3个参数,这些参数分别表示起始值、终止值和步长。
语法如下:
python复制代码 range(start, stop, step)
-
start
:可选参数,表示序列的起始值。默认为0。 -
stop
:必需参数,表示序列的终止值。即生成的整数序列的最大值,不包括该值。 -
step
:可选参数,表示序列的步长。默认为1。
下面是一些使用range()
函数的例子:
-
使用一个参数:
for i in range(5): print(i) # 输出: 0, 1, 2, 3, 4
-
使用两个参数:
for i in range(3, 8): print(i) # 输出: 3, 4, 5, 6, 7
例子:start
参数默认为0,因此不指定也可以。
-
使用三个参数:
for i in range(0, 10, 2): print(i) # 输出: 0, 2, 4, 6, 8
在这个例子中,start
参数为0,stop
参数为10(不包括10),step
参数为2。
3.3.3 for循环
作用:for
循环是一种常用的控制流语句,用于遍历序列(如列表、元组、字符串等)或其他可迭代对象
语法:依次将每个元素赋值给循环变量,执行循环体中的代码。
例子:
fruits = ['apple', 'banana', 'cherry'] for fruit in fruits: print(fruit)
在上面的代码中,我们定义了一个包含三个字符串元素的列表fruits
,然后使用for
循环遍历该列表,并将每个元素赋值给变量fruit
,在循环体中打印出该变量。执行这段代码后,会依次输出apple
、banana
和cherry
这三个字符串。
3.3.4 循环嵌套
4. 序列结构
4.1 字符串
4.1.1 字符串的定义
作用:字符串是由零个或多个字符组成的一种数据类型。字符串的字面值可以使用单引号、双引号或三引号定义,如下所示:
str1 = 'Hello, World!' str2 = "Hello, World!" str3 = '''Hello, World!'''
注意,Python中的字符串是不可变的,这意味着一旦一个字符串被创建,就不能更改它的值。另外,Python支持多行字符串,可以通过在引号中包含换行符来实现:
str4 = '''This is a multi-line string.'''
还可以使用加号(+)将字符串连接起来,或者使用字符串方法来操作字符串。例如:
str5 = 'Hello' + ' ' + 'World' + '!' print(str5) # 输出:'Hello World!'
4.1.2 字符串的下标
作用:在Python中,字符串是一种序列类型,可以使用下标来访问字符串中的字符。字符串下标从0开始,可以使用正数或负数表示。
语法:
python str[index]
其中,str
是要访问的字符串,index
是要访问的下标。
作用:
-
访问字符串中的特定字符。
-
通过索引修改字符串中的字符。
-
切片操作,可以同时访问多个字符。
例子:
str = 'Hello, World!' print(str[0]) # 输出:'H' print(str[7]) # 输出:'W' print(str[-1]) # 输出:'!'
注意:
-
如果下标越界,Python会抛出
IndexError
异常。 -
如果下标为负数,Python会从字符串末尾开始计数。例如,
str[-1]
表示最后一个字符,str[-2]
表示倒数第二个字符,以此类推。 -
索引:索引是用来获取序列中某个位置的元素的方法。在Python中,我们通过在序列名后面添加方括号
[]
和索引值来获取特定位置的元素。索引从0开始,因此第一个元素的索引是0,第二个元素的索引是1,依此类推。如果索引是负数,那么它是从末尾开始计数的。例如:# 定义一个字符串 s = 'Hello, World!' # 使用索引获取第一个字符 print(s[0]) # 输出:'H' # 使用索引获取倒数第二个字符 print(s[-2]) # 输出:'l'
切片:切片是用来获取序列中一部分元素的方法。在Python中,我们通过在序列名后面添加方括号
[]
和切片范围来获取序列的一部分。切片范围由起始索引、结束索引和步长组成,分别表示为start:end:step
。起始索引和结束索引都是可选的,如果省略,默认为0和序列的长度。步长也是可选的,如果省略,默认为1。例如:# 定义一个列表 lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 使用切片获取列表的前三个元素 print(lst[:3]) # 输出:[0, 1, 2] # 使用切片获取列表的最后三个元素 print(lst[5:8]) # 输出:[5, 6, 7] # 使用切片获取列表的偶数元素(步长为2) print(lst[::2]) # 输出:[0, 2, 4, 6, 8]
综合应用:在实际编程中,我们经常将索引和切片结合起来使用,以便更方便地操作序列。例如,我们可以使用索引来修改序列中的特定元素,然后使用切片来获取序列的一部分并进行进一步处理。例如:
# 定义一个字符串 s = 'Hello, World!' # 使用索引修改字符串的第五个字符 s[4] = 'a' print(s) # 输出:'Hello, Warld!' # 使用切片获取修改后的字符串的前五个字符并进行打印 print(s[:5]) # 输出:'Hello,'
4.1.3 字符串的常用操作方法
-
连接(Concatenation):将两个或多个字符串连接在一起。在Python中,可以使用加号(+)进行连接。
str1 = 'Hello' str2 = 'World' str3 = str1 + ' ' + str2 # 结果是 'Hello World'
-
切片(Slicing):获取字符串的一部分。切片操作使用冒号(:)表示,格式为
start:end:step
。
str = 'Hello, World!' print(str[0:5]) # 输出:'Hello' print(str[-2:]) # 输出:'ld!'
-
替换(Substitution):在字符串中替换一个或多个字符或子串。
str = 'Hello, World!' new_str = str.replace('World', 'Python') # 将 'World' 替换为 'Python' print(new_str) # 输出:'Hello, Python!'
-
分割(Splitting):将字符串分割成多个部分。可以使用逗号(,)进行分割。
str = 'Hello, World!' parts = str.split(',') # 以逗号分割字符串 print(parts) # 输出:['Hello', ' World!']
-
大小写转换:将字符串中的字符转换为大写或小写。
str = 'Hello, World!' print(str.upper()) # 输出:'HELLO, WORLD!' print(str.lower()) # 输出:'hello, world!'
-
检查字符串长度:获取字符串的长度。
str = 'Hello, World!' print(len(str)) # 输出:13
跳过:通常指的是在循环中跳过特定的迭代。这可以通过使用continue
语句来实现。continue
语句会使程序跳过当前循环的剩余部分,并立即开始下一次循环。
例如,下面的代码会打印出0到9之间的所有奇数(包括0):
for i in range(10): if i % 2 == 0: continue print(i)
在这个例子中,当i
是偶数时,continue
语句会被执行,导致程序跳过本次循环的剩余部分(即print(i)
语句),并立即开始下一次循环。因此,只有当i
是奇数时,print(i)
语句才会被执行。
Python 转义字符
在需要在字符中使用特殊字符时,python 用反斜杠 ** 转义字符。如下表:
转义字符 | 描述 |
---|---|
(在行尾时) | 续行符 |
\ | 反斜杠符号 |
' | 单引号 |
" | 双引号 |
\a | 响铃 |
\b | 退格(Backspace) |
\e | 转义 |
\000 | 空 |
\n | 换行 |
\v | 纵向制表符 |
\t | 横向制表符 |
\r | 回车 |
\f | 换页 |
\oyy | 八进制数,y 代表 0~7 的字符,例如:\012 代表换行。 |
\xyy | 十六进制数,以 \x 开头,yy代表的字符,例如:\x0a代表换行 |
\other | 其它的字符以普通格式输出 |
成员运算符定义
作用:成员运算符in
和not in
用于检查序列(如列表、元组、字符串等)或集合(如集、字典等)中是否包含某个元素或子集。
语法:
expr1 in expr2 expr1 not in expr2
其中,expr1
是待检查的元素或子集,expr2
是待检查的序列或集合。如果expr1
是expr2
的成员,则返回True;否则返回False。
以下是成员运算符的示例:
# 列表中是否包含某个元素 fruits = ['apple', 'banana', 'orange'] if 'apple' in fruits: print("苹果在水果列表中") # 集合中是否包含某个子集 colors1 = {'red', 'green', 'blue'} colors2 = {'red', 'green'} if colors2 in colors1: print("颜色集合2是颜色集合1的子集") # 字符串中是否包含某个子字符串 text = "Hello, world!" if "world" in text: print("文本中包含'world'子字符串")
在上面的示例中,我们首先定义了一个包含三个元素的列表fruits
,然后使用成员运算符检查"apple"是否在fruits
中。接着,我们定义了两个集合colors1
和colors2
,并使用成员运算符检查colors2
是否是colors1
的子集。最后,我们定义了一个字符串text
,并使用成员运算符检查"world"是否在text
中。
4.2 列表
4.2.1 列表的定义
由一系列字符组成的不可变序列容器
由一系列变量组成的可变序列容器
4.2.1.1 定义空列表
定义:空列表的定义非常简单。只需要使用方括号([])包围,没有任何元素即可。
语法:
python empty_list = []
这样就定义了一个名为empty_list
的空列表。你可以随时向这个列表添加元素
4.2.1.2 定义普通列表
语法:你可以使用方括号([]
)来定义一个普通列表(也称为Python列表)。
作用:列表是一种有序的集合,可以包含任何类型的元素,例如数字、字符串、其他列表等。下面是一个定义普通列表的示例:
python复制代码 my_list = [1, 2, 3, 'apple', 'banana', [1, 2, 3]]
在这个例子中,我们创建了一个名为my_list
的列表,它包含了一些数字、字符串和其他列表。你可以通过索引访问列表中的元素,例如:
print(my_list[0]) # 输出:1 print(my_list[3]) # 输出:'apple'
你还可以使用切片操作来访问列表中的多个元素。例如,my_list[1:4]
将返回一个新的列表,包含my_list
中的第2个到第4个元素:
python复制代码 print(my_list[1:4]) # 输出:[2, 3, 'apple']
除了直接赋值,你还可以使用append()
方法向列表中添加新元素,使用remove()
方法删除元素等。这些方法使你可以对列表进行操作和修改。
4.2.1.3 定义嵌套列表
作用:嵌套列表是指一个列表中包含有另一个列表作为其元素。这样的结构可以用来表示复杂的数据结构。
例如,下面是一个包含三个嵌套列表的列表:
python复制代码 nested_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
在这个例子中,nested_list
是一个包含三个子列表的列表。每个子列表都包含三个整数。
使用嵌套列表可以实现很多功能,例如表示二维数据、创建多维数组等。同时,Python中也提供了很多处理嵌套列表的内置函数和方法,例如 append()
, extend()
, insert()
, pop()
, remove()
, index()
等。
4.2.2 列表的遍历(与for结合运用)
(注意使用切片,不建议,原因是因为通过切片拿元素会重新形成新列表)
4.2.2.1 遍历普通列表
语法:遍历普通列表的语法主要是使用for循环。
首先,我们来创建一个普通列表:
python复制代码 my_list = [1, 2, 3, 4, 5]
现在,我们想要遍历这个列表,也就是访问列表中的每一个元素。我们可以使用for循环来实现:
for element in my_list: print(element)
在这段代码中,for
循环会依次将my_list
中的每个元素赋值给变量element
,然后执行循环体中的代码。在这个例子中,循环体只是简单地打印出element
的值。所以,这段代码的输出会是:
1 2 3 4 5
除了打印元素,你也可以在循环体内对元素进行操作。例如,我们可以将每个元素加倍并创建新的列表:
doubled_list = [element * 2 for element in my_list] print(doubled_list) # 输出 [2, 4, 6, 8, 10]
在这个例子中,我们使用了列表推导式(list comprehension),它是一种更简洁的创建列表的方式。这段代码会遍历my_list
中的每个元素,将其乘以2,然后创建一个新的列表doubled_list
。
4.2.2.2 遍历嵌套列表
作用:遍历嵌套列表通常使用嵌套的for循环。嵌套循环允许您访问每个列表的元素,并对其执行操作。
例子:
# 定义一个嵌套列表 nested_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] # 遍历嵌套列表并打印每个元素 for sublist in nested_list: for element in sublist: print(element)
这段代码会输出:
1 2 3 4 5 6 7 8 9
在这个例子中,外部的for循环遍历了嵌套列表中的每个子列表。然后,对于每个子列表,内部的for循环遍历其元素,并打印出每个元素的值。
你也可以在循环体内对元素进行操作。例如,我们可以将每个元素加倍并创建新的嵌套列表:
# 定义一个嵌套列表 nested_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] # 遍历嵌套列表并创建新的嵌套列表 new_nested_list = [[element * 2 for element in sublist] for sublist in nested_list] print(new_nested_list) # 输出 [[2, 4, 6], [8, 10, 12], [14, 16, 18]]
在这个例子中,我们使用了列表推导式来创建一个新的嵌套列表。外部的for循环遍历原始嵌套列表中的每个子列表。然后,内部的列表推导式遍历每个子列表中的元素,将其乘以2,并创建一个新的子列表。最后,我们创建了一个新的嵌套列表,其中包含经过处理的元素。
4.2.3 列表的常用操作方法
4.2.3.1 查找元素下标index
要从列表中获取元素,可以使用索引。索引从0开始,因此第一个元素的索引是0,第二个元素的索引是1,依此类推。
-
通过切片获取元素:如果要获取列表中的多个元素,可以使用切片。这是通过在列表名称后面放置一个方括号和切片范围来完成的。切片范围是一个由两个索引组成的元组,第一个索引是开始位置(包括),第二个索引是结束位置(不包括)。还可以在切片范围中添加第三个值来指定步长。
my_list = ['apple', 'banana', 'cherry', 'date', 'elderberry'] print(my_list[1:4]) # 输出:['banana', 'cherry', 'date'] print(my_list[::2]) # 输出:['apple', 'cherry', 'date' , 'elderberry']
-
索引(Indexing):获取字符串中特定位置的字符。索引从0开始。
str = 'Hello, World!' print(str[0]) # 输出:'H' print(str[7]) # 输出:'W'
-
通过索引获取元素:如果要获取列表中的特定元素,可以使用索引。这是通过在列表名称后面放置一个方括号和索引号来完成的。如果索引超出了列表的长度,Python将引发IndexError。
my_list = ['apple', 'banana', 'cherry'] print(my_list[1]) # 输出:'banana'
4.2.3.1 修改特定下标索引的值
4.2.3.3 指定位置插入元素insert
-
insert():这个方法可以在列表的指定位置插入元素。它需要两个参数,第一个参数是要插入的位置的索引,第二个参数是要插入的元素。
my_list = [1, 2, 3] my_list.insert(1, 'a') print(my_list) # 输出:[1, 'a', 2, 3]
4.2.3.4 元素的追加append
-
添加元素到列表:
Python提供了几种方法来向列表添加元素。
-
append():这个方法将元素添加到列表的末尾。
my_list = [1, 2, 3] my_list.append(4) print(my_list) # 输出:[1, 2, 3, 4]
4.2.3.4 批量追加extend
-
extend():这个方法可以将一个列表(或任何可迭代的元素)添加到当前列表的末尾。这相当于在列表的末尾追加了另一个列表的所有元素。
my_list = [1, 2, 3] my_list.extend([4, 5]) print(my_list) # 输出:[1, 2, 3, 4, 5]
4.2.3.5 删除元素del/pop
2,删除元素
-
使用
del
语句:(根据位置删除)
del
语句可以用来删除列表中的元素。你需要提供要删除元素的索引。
my_list = [1, 2, 3, 4, 5] del my_list[1] # 删除第二个元素 print(my_list) # 输出:[1, 3, 4, 5]
4.2.3.6 删除元素remove
-
使用
remove
方法:(根据元素删除)
remove
方法可以根据值来删除元素。它会找到第一个匹配的元素并删除。
my_list = [1, 2, 3, 4, 5] my_list.remove(3) # 删除值为3的元素 print(my_list) # 输出:[1, 2, 4, 5]
4.2.3.7 清空列表clear
作用:这个内置方法会移除列表中的所有元素,使其变为空列表。
list = [1, 2, 3, 4, 5] list.clear() print(list) # 输出:[]
使用del
语句。这个语句不仅可以删除列表,也可以删除其他Python对象。
list = [1, 2, 3, 4, 5] del list[:] print(list) # 输出:[]
这两种方法都可以用来清空列表,但在某些情况下,它们可能会有不同的效果。例如,clear()
方法不会改变列表的长度,而del
语句会。此外,clear()
方法可能会保留列表中未被使用的元素,而del
语句则会彻底删除它
4.2.3.8 统计指定元素的个数count
语法:
python复制代码 list.count(element)
其中,list
是你要统计的列表,element
是你要统计的元素。
例字:如果你有一个列表 fruits = ['apple', 'banana', 'cherry', 'apple', 'cherry', 'cherry']
,你可以使用 count()
方法来统计 'apple' 在列表中出现的次数:
python复制代码 print(fruits.count('apple')) # 输出:2
这个例子中,count()
方法返回了 'apple' 在 fruits
列表中出现的次数,即2。
4.2.3.9 统计列表长度len
len()
函数用于返回一个对象(如列表,元组,字符串等)的长度或项目数。
语法:
python复制代码 len(object)
在这里,object
是要计算长度的对象。
例子:如果你有一个列表,你可以使用len()
函数来计算列表中的元素数量:
my_list = [1, 2, 3, 4, 5] print(len(my_list)) # 输出:5
len()`函数也可以用于其他数据类型,如字符串,元组等:
my_string = 'Hello, world!' print(len(my_string)) # 输出:13 my_tuple = (1, 2, 3, 4, 5) print(len(my_tuple)) # 输出:5
此外,len()
函数还可以用于计算某些对象的长度,例如文件对象或字典对象。
这是一个例子:
file = open('myfile.txt', 'r') print(len(file.read())) # 输出:文件的字符数
额外:join将列表转换为字符串。将多个字符串拼接成一个
result = "连接符".join(列表)
type可以查看类型是列表还是字符串
练习:在控制台中循环输入字符串,如果输入空则停止。
最后打印所有内容。(拼接后的字符串)
ever_one = [] while True: number01 = input ("请输入字符串") if number01 == " ": break ever_one.append(number01) ever_one = "".join() print(ever_one)
split是将字符串转换为列表
4.2.1.4 列表推导式
作用:用于创建列表。它可以将一些复杂的循环语句简化为一行代码。
语法如下:
python复制代码 [expression for item in iterable]
其中:
-
expression
是一个表达式,表示对每个item
进行操作并生成一个新元素。 -
item
是iterable
中的每个元素。 -
iterable
是一个可迭代对象,如列表、元组、字符串等。
例如,要创建一个包含 1 到 10 的平方数的列表,可以使用以下列表推导式:
squares = [x**2 for x in range(1, 11)] print(squares) # 输出: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
在上面的例子中,expression
是 x**2
,表示计算每个元素的平方,而 iterable
是 range(1, 11)
,表示从 1 到 10 的整数范围。通过列表推导式,我们可以轻松地创建一个包含平方数的列表。
总结:
1,创建[数据],list(容器)
2,定位:索引 切片
从列表中获取一片元素组成新列表
变量 = 切片名[切片]
修改一片元素
列表名[切片] = 变量
3,删除
del 列表名[索引/切片]
列表名.remove(元素)
从列表中删除多个元素,倒序删除,建议倒序删除
4.增加:
列表名.append(元素)默认放在最后一个
列表名.insert(索引,元素)
5.获取所有元素
print(列表名)只是打印列表并不是获取所有元素
获取所有元素
for item in 列表名:
print(列表名)
倒着拿
for item in 列表名[::-1]
print(列表名)
for item in range(len(列表名)-1 ,-1 ,-1):
print(列表名[1])
列表扩容原理:
1,列表都会预留空间,
2,当预留空间不足时会创建一个新列表(开一个更大的空间)
3,将原有的数据拷贝过来
4,替换引用、
4.3 元组tuple
4.3.1 元组的定义
1,由一系列变量组成的不可变序列容器。(不会像列表一样预留空间,按需分配)
2,不可变是指一旦创建,不可以再添加/删除/修改元素。
3,元组不可修改,但可以对元组进行接连组合。
4.3.1.1 定义空元组
空元组是一个不包含任何元素的元组,用两个括号表示,例如:()
。在Python中,你可以创建一个空元组,如下所示:
python复制代码 empty_tuple = ()
这个语句创建了一个空元组并将其赋值给变量 empty_tuple
。你可以通过调用 len()
函数来验证这个元组是否为空,如下所示:
python复制代码 print(len(empty_tuple)) # 输出: 0
这将输出 0
,表示这个元组没有任何元素。
4.3.1.2 定义普通元组
普通元组是一种常见的元组类型,其中包含的元素可以是不同的数据类型,而且元组中不要求所有元素都具有相同的值。与普通元组相对的是普通元组中的元素必须具有相同的数据类型。
例如,以下是一个包含不同数据类型的普通元组的示例:
python复制代码 tup = (1, "Hello", 3.14, True)
在这个例子中,元组包含了一个整数、一个字符串、一个浮点数和一个布尔值。这些元素的数据类型都不同,因此这是一个普通元组的示例。
4.3.1.3 定义嵌套元组
嵌套元组(Nested Tuple)是指元组中包含其他元组的元组。这种结构可以用来表示复杂的数据结构,例如矩阵或树等。
例如,以下是一个包含嵌套元组的示例:
python复制代码 nested_tup = ((1, 2), (3, 4), (5, 6))
在这个例子中,最外层的元组包含三个元素,每个元素都是一个包含两个元素的元组。因此,这是一个嵌套元组的示例。
4.3.2 元组的遍历
4.3.2.1 遍历普通元组
作用:要遍历普通元组,可以使用循环结构来遍历元组中的每个元素。
例子:假设有一个名为 tup
的普通元组,可以使用以下代码来遍历元组中的所有元素:
for elem in tup: print(elem)
这将输出元组中的每个元素
2 3 4 5
在这个例子中,tup
是一个包含不同数据类型的普通元组,因此每个元素都是不同的数据类型。循环结构将遍历元组中的每个元素,并将它们分别赋值给变量 elem
,然后打印出来。
4.3.2.2 遍历嵌套元组
要遍历嵌套元组,可以使用双重循环结构来遍历元组中的每个元素。例如,假设有一个名为 nested_tup
的嵌套元组,可以使用以下代码来遍历元组中的所有元素:
for sub_tup in nested_tup: for elem in sub_tup: print(elem)
这将输出嵌套元组中的每个元素,例如:
1 2 3 4 5 6
在这个例子中,最外层的元组包含三个元素,每个元素都是一个包含两个元素的元组。第一层循环将遍历最外层元组中的每个元素,即每个包含两个元素的元组。然后,第二层循环将遍历每个元组中的每个元素,并将它们分别赋值给变量 elem
,然后打印出来。
4.3.3 元组的常用操作方法
4.3.3.1 查找方法 index
作用:index()
方法用于返回元组中某个元素的索引位置。如果元素不存在于元组中,该方法将抛出ValueError
异常。
以下是index()
方法的语法:
python复制代码 tuple.index(value)
其中,tuple
是要查找的元组,value
是要查找的元素。
例子:
my_tuple = (3, 4, 5, 6, 7) # 查找元素4的索引位置 index = my_tuple.index(4) print(index) # 输出:1
在上面的例子中,我们定义了一个包含整数的元组my_tuple
,并使用index()
方法查找元素4
的索引位置。该方法的返回值是1
,表示4
在元组中的位置是第二个。
4.3.3.2 统计方法 count
作用:count()
方法是用于统计某个元素在列表中出现的次数。
语法:
python复制代码 list.count(value)
其中,list
是要统计的列表,value
是要统计的元素。
例子:
my_list = [1, 2, 3, 4, 4, 5] # 统计元素4在列表中出现的次数 类 count = my_list.count(4) print(count) # 输出:2
在上面的例子中,我们定义了一个包含整数的列表my_list
,并使用count()
方法统计元素4
在列表中出现的次数。该方法的返回值是2
,表示4
在列表中出现了两次。
4.3.3.3 统计个数len
作用:len()
函数用于返回一个对象(如列表、元组、字符串等)的长度或项目数。
语法:
python复制代码 len(object)
其中,object
是要计算长度的对象。
例子:
my_list = [1, 2, 3, 4, 5] # 计算列表的长度 length = len(my_list) print(length) # 输出:5
在上面的例子中,我们定义了一个包含整数的列表my_list
,并使用len()
函数计算列表的长度。该函数的返回值是5
,表示列表中有5个元素。
4.3.4 元组推导式
元组推导式(Tuple comprehension)是 Python 语言中的一种语法结构,它允许你在一行代码中生成一个元组(tuple)。元组推导式的语法和列表推导式(List comprehension)类似,只是在结果中返回一个元组而不是列表。
语法:
python复制代码 [(expression) for item in iterable]
其中,expression
是一个表达式,它将对 iterable
中的每个元素执行,并返回一个元组。item
是 iterable
中的每个元素的临时名称,可以在表达式中使用。
例子,演示如何使用元组推导式生成一个包含数字 1 到 5 的元组:
t = [(x, x**2) for x in range(1, 6)] print(t) # 输出:[(1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]
在这个例子中,我们使用了 range(1, 6)
来生成一个包含数字 1 到 5 的可迭代对象。然后,我们使用元组推导式将每个数字与其平方值组成一个元组,并将这些元组存储在变量 t
中。最后,我们打印出 t
的值,可以看到它是一个包含多个元组的元组。
元组推导式的作用类似于列表推导式,可以简化代码并提高代码的可读性。它通常用于生成一个包含多个值的元组,这些值可以通过表达式进行计算或处理。
4.4 集合
4.4.1 集合的定义
集合(set)是一个无序且不重复的元素序列。可以使用大括号 {} 或 set() 函数定义一个集合。
例子:
# 创建一个空集合 empty_set = set() print(empty_set) # 输出:set() # 创建一个包含几个元素的集合 fruits = set(["apple", "banana", "cherry"]) print(fruits) # 输出:{'apple', 'banana', 'cherry'} # 创建一个包含重复元素的集合,重复元素会被自动去除 duplicates = set([1, 2, 2, 3, 4, 4, 5, 5]) print(duplicates) # 输出:{1, 2, 3, 4, 5}
这个例子展示了如何创建不同类型的集合。第一个集合是空的,第二个集合包含了一些水果,而第三个集合包含了几个重复的数字,但在集合中,这些重复的数字只会被存储一次。
4.4.2 添加新的元素 add
作用:add
方法是集合对象(set)的一个方法,用于将一个新元素添加到集合中。
语法:
python复制代码 set.add(element)
其中,set
是要添加元素的集合对象,element
是要添加的元素。
例子:
# 创建一个空集合 my_set = set() # 添加元素到集合中 my_set.add(1) my_set.add(2) my_set.add(3) # 打印集合中的元素 print(my_set) # 输出:{1, 2, 3}
在这个例子中,我们首先创建了一个空集合my_set
,然后使用add
方法将元素1、2和3添加到集合中。最后,我们打印出集合中的元素,可以看到元素已经成功添加到了集合中。
4.4.3 移除元素 remove
作用:remove
方法是集合对象(set)的一个方法,用于从集合中移除一个指定的元素。
语法:
python复制代码 set.remove(element)
其中,set
是包含要移除元素的集合对象,element
是要移除的元素。
例子:
# 创建一个包含几个元素的集合 my_set = set([1, 2, 3, 4, 5]) # 从集合中移除一个元素 my_set.remove(3) # 打印集合中的元素 print(my_set) # 输出:{1, 2, 4, 5}
在这个例子中,我们首先创建了一个包含几个元素的集合my_set
,然后使用remove
方法从集合中移除元素3。最后,我们打印出集合中的元素,可以看到元素3已经成功从集合中移除。
4.4.4 随机取出 pop
作用:pop
方法是集合对象(set)的一个方法,用于随机删除并返回集合中的一个元素。由于集合是无序的,因此pop
方法每次调用时都会随机选择一个元素进行删除并返回。
语法:
python复制代码 element = set.pop()
其中,set
是要弹出元素的集合对象,element
是pop
方法返回的被删除的元素。
例子:
# 创建一个包含几个元素的集合 my_set = set([1, 2, 3, 4, 5]) # 随机弹出一个元素并打印 print(my_set.pop()) # 输出可能是1、2、3、4或5中的任意一个,因为集合是无序的 # 打印集合中的元素,可以看到已经有一个元素被移除了 print(my_set) # 输出可能是{1, 2, 4},{1, 3, 5},{2, 3, 4},{2, 4, 5}等中的一个,因为有一个元素被移除了
需要注意的是,每次调用pop
方法都会随机删除一个元素,因此多次调用pop
方法会导致集合中元素数量的减少。另外,如果集合已经为空,再次调用pop
方法会引发KeyError
异常。因此,在使用pop
方法时,需要先判断集合是否为空。
希望这个例子可以帮助你理解Python中集合的pop
方法的作用和语法。
4.4.5 清空集合 clear
作用:clear
方法是列表(list)的一个方法,用于移除列表中的所有元素,使列表变为空列表。
语法:
python复制代码 list.clear()
其中,list
是要清空的列表对象。
例子:
# 创建一个包含几个元素的列表 my_list = [1, 2, 3, 4, 5] # 清空列表 my_list.clear() # 打印清空后的列表 print(my_list) # 输出:[]
在这个例子中,我们首先创建了一个包含几个元素的列表my_list
,然后使用clear
方法清空了列表。最后,我们打印出清空后的列表,可以看到列表已经变为空列表。
需要注意的是,调用clear
方法后,列表中所有元素都会被移除,因此再次访问这些元素会引发错误。另外,clear
方法不会返回任何值,只是简单地清空列表。如果需要对列表进行多次操作,可以先将列表备份一份,以防误清空列表导致数据丢失。
4.4.6 取两个集合差集 difference
作用:可以使用difference
方法来获取两个集合的差集,也就是在一个集合中但不在另一个集合中的元素。
语法:
python复制代码 set1.difference(set2)
或者可以使用减号操作符-
来获取差集:
python复制代码 set1 - set2
其中,set1
和set2
是两个要进行差集运算的集合对象。
作用:
difference
方法返回一个新的集合,该集合包含所有在set1
中但不在set2
中的元素。如果set1
和set2
有重复的元素,那么这些重复元素只会被计算一次。该方法不会修改原始的集合对象,而是返回一个新的集合对象。
例子:
# 创建两个集合对象 set1 = {1, 2, 3, 4, 5} set2 = {3, 4, 5, 6, 7} # 使用difference方法获取差集 diff_set = set1.difference(set2) print(diff_set) # 输出:{1, 2} # 使用减号操作符获取差集 diff_set = set1 - set2 print(diff_set) # 输出:{1, 2}
在这个例子中,我们创建了两个集合对象set1
和set2
,然后使用difference
方法和减号操作符分别获取了它们的差集。可以看到,差集是一个包含所有在set1
中但不在set2
中的元素的集合对象。
4.4.7 消除2个集合的差集
语法:如果你想要消除两个集合的差值,你可以使用集合操作中的对称差集(Symmetric Difference)操作。对称差集是指两个集合中不重复的元素组成的集合。
Python的set
数据结构提供了一个方法叫做symmetric_difference
来执行这个操作。
例子:
set1 = {1, 2, 3, 4, 5} set2 = {3, 4, 5, 6, 7} # 使用symmetric_difference方法获取对称差集 symmetric_diff = set1.symmetric_difference(set2) print(symmetric_diff) # 输出:{1, 2, 6, 7}
在这个例子中,对称差集是所有在set1
或set2
中但不同时在两个集合中的元素组成的集合。所以,如果你想要消除两个集合的差值,你可以使用symmetric_difference
方法。
4.4.8 2个集合合并为1
语法:你可以使用union
方法或者|
操作符来合并两个集合。union
方法会返回一个新的集合,包含两个集合中的所有元素。|
操作符也是一个快捷方式,用于合并两个集合。
以下是一个例子:
set1 = {1, 2, 3, 4, 5} set2 = {4, 5, 6, 7, 8} # 使用union方法合并两个集合 merged_set = set1.union(set2) print(merged_set) # 输出:{1, 2, 3, 4, 5, 6, 7, 8} # 或者使用|操作符来合并两个集合 merged_set = set1 | set2 print(merged_set) # 输出:{1, 2, 3, 4, 5, 6, 7, 8}
在这个例子中,set1
和set2
被合并为一个新的集合merged_set
,包含所有的元素。
4.4.9 统计集合元素数量 len
作用:len()
函数用于获取集合(set)中元素的数量。集合是无序的,不包含重复元素的集合,因此len()
函数返回集合中元素的数量。
语法:
scss复制代码 len(set)
其中,set
是要计算元素数量的集合对象。
作用:
-
计算集合中元素的数量。
-
确定集合是否为空。
例子:
# 创建一个集合对象 my_set = {1, 2, 3, 4, 5} # 使用len()函数计算集合中元素的数量 element_count = len(my_set) print(element_count) # 输出:5 # 检查集合是否为空 if len(my_set) == 0: print("集合为空") else: print("集合不为空")
在这个例子中,我们创建了一个包含5个元素的集合my_set
,然后使用len()
函数计算了集合中元素的数量,并打印出来。接着,我们使用len()
函数检查集合是否为空,并打印相应的结果。
4.4.10 集合的遍历
作用:集合的遍历是指通过循环访问集合中的每个元素并进行操作。在Python中,可以使用for循环来遍历集合。
语法:
for element in set: # 对element进行操作
其中,set
是要遍历的集合对象,element
是集合中的每个元素。
例子:
# 创建一个集合对象 my_set = {1, 2, 3, 4, 5} # 遍历集合并打印每个元素 for element in my_set: print(element)
输出:
1 2 3 4 5
在这个例子中,我们创建了一个包含5个元素的集合my_set
,然后使用for循环遍历了集合中的每个元素,并将它们打印出来。可以看到,遍历集合可以让我们依次访问集合中的每个元素,并对它们进行操作。
4.4.11 集合推导式
语法:我们可以使用for循环和if语句来推导(或生成)新的集合。这种操作被称为集合推导式。以下是一个基本的集合推导式的例子:
# 创建一个集合对象 my_set = {1, 2, 3, 4, 5} # 使用集合推导式生成一个新的集合,包含my_set中的偶数元素 new_set = {x for x in my_set if x % 2 == 0} print(new_set) # 输出:{2, 4}
在这个例子中,我们使用了集合推导式来生成一个新的集合,包含my_set
中的偶数元素。集合推导式的语法是:{expression for item in iterable if condition}
,其中expression
是要生成的元素,item
是迭代器中的每个元素,iterable
是要迭代的对象,condition
是一个可选的条件语句。在上述例子中,x
是迭代器中的每个元素,my_set
是要迭代的对象,x % 2 == 0
是条件语句,表示只包含偶数元素。
4.5 字典
(时间(cpu)是最快的,但是会开很多的空间(内存))利用空间换取时间。
4.5.1 字典的定义
作用:字典(dictionary)是一种无序、可变、可迭代的数据类型,它由键(key)和对应的值(value)组成。每个键都映射到一个值,这种映射在字典的整个生命周期中保持不变。键和值之间用冒号(:)分隔,而键值对之间用逗号(,)分隔。例如:
python复制代码 my_dict = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
在这个例子中,'key1'、'key2'、'key3' 是字典的键,'value1'、'value2'、'value3' 是与这些键关联的值。
字典的键必须是唯一的,而值可以是任何数据类型。此外,Python中的字典是可变的,这意味着您可以添加、删除或更改字典中的条目。
4.5.2 字典的操作
4.5.2.1 字典元素的增加
可以使用以下语法向字典中添加元素:
python复制代码 my_dict[key] = value
其中,my_dict
是要添加元素的字典,key
是要添加的键,value
是与该键关联的值。
添加元素的作用是扩展字典的键值对集合。当使用 my_dict[key] = value
语法时,如果指定的键 key
不存在于字典中,则将其添加到字典中,并将其关联的值设置为指定的值 value
。如果指定的键已经存在于字典中,则更新该键对应的值,将其设置为新的值 value
。
下面是一个例子:
# 创建一个空字典 my_dict = {} # 向字典中添加一个键值对 my_dict['name'] = 'Alice' print(my_dict) # 输出:{'name': 'Alice'} # 向字典中添加多个键值对 my_dict['age'] = 25 my_dict['city'] = 'New York' print(my_dict) # 输出:{'name': 'Alice', 'age': 25, 'city': 'New York'} # 更新字典中的值 my_dict['age'] = 26 print(my_dict) # 输出:{'name': 'Alice', 'age': 26, 'city': 'New York'}
4.5.2.2 字典元素的删除pop
可以使用以下语法来删除字典中的元素:
python复制代码 del my_dict[key]
其中,my_dict
是要删除元素的字典,key
是要删除的键。
删除字典元素的作用是移除指定键及其关联的值。使用 del my_dict[key]
语法时,如果指定的键存在于字典中,则将其从字典中删除,并释放该键关联的内存空间。如果指定的键不存在于字典中,则Python将引发KeyError异常。
例子:
# 创建一个字典 my_dict = {'name': 'Alice', 'age': 25, 'city': 'New York'} # 删除一个键值对 del my_dict['age'] print(my_dict) # 输出:{'name': 'Alice', 'city': 'New York'} # 尝试删除不存在的键值对(将引发KeyError异常) try: del my_dict['job'] except KeyError: print("The key 'job' does not exist in the dictionary.")
4.5.2.3 清空字典clear
可以使用以下语法来清空一个字典:
python复制代码 my_dict.clear()
清空字典的作用是将字典中的所有键值对全部删除,使其变为一个空字典。
例子:
# 创建一个字典 my_dict = {'name': 'Alice', 'age': 25, 'city': 'New York'} # 清空字典 my_dict.clear() # 输出清空后的字典 print(my_dict) # 输出:{}
4.5.2.4 遍历字典所有值 dic.values
你可以使用 values()
方法来遍历字典的所有值。以下是一个例子:
# 创建一个字典 my_dict = {'name': 'Alice', 'age': 25, 'city': 'New York'} # 遍历字典的所有值 for value in my_dict.values(): print(value)
在这个例子中,my_dict.values()
返回一个包含字典所有值的视图。然后,我们使用 for
循环遍历这个视图,打印出每个值。
4.5.2.5 字典元素的删除pop/popitem
可以使用 del
语句删除字典中的单个元素。语法如下:
python复制代码 del my_dict[key]
其中,my_dict
是要删除元素的字典,key
是要删除的键。
如果要删除字典中的多个元素,可以使用 del
语句和括号来一次删除多个键值对。语法如下:
python复制代码 del my_dict[(key1, key2, ...)]
其中,my_dict
是要删除元素的字典,(key1, key2, ...)
是要删除的键的元组。
注意,如果要删除字典中的键不存在,Python会引发 KeyError
异常。为了避免这个异常,可以使用 dict.pop()
方法删除键并返回其值。如果键不存在,该方法将引发 KeyError
异常。
例如:
my_dict = {'name': 'Alice', 'age': 25, 'city': 'New York'} print(my_dict) # 输出:{'name': 'Alice', 'age': 25, 'city': 'New York'} del my_dict['age'] # 删除键为'age'的元素 print(my_dict) # 输出:{'name': 'Alice', 'city': 'New York'} my_dict.pop('name') # 删除键为'name'的元素并返回其值'Alice' print(my_dict) # 输出:{'city': 'New York'}
4.5.3 字典的遍历
4.5.3.1 遍历所有键值对items
字典的.items()
方法返回一个包含字典所有键值对的视图。这个视图对象可以用于遍历字典的键值对。
语法:
python复制代码 dict.items()
例子:
my_dict = {'name': 'Alice', 'age': 25, 'city': 'New York'} # 遍历字典的键值对 for key, value in my_dict.items(): print('Key:', key) print('Value:', value)
输出:
Key: name Value: Alice Key: age Value: 25 Key: city Value: New York
在上面的例子中,我们使用了for
循环和.items()
方法来遍历字典my_dict
的所有键值对。在每次循环中,我们打印出当前的键和值。
4.5.3.2 遍历字典所有键 keys
你可以使用for
循环和字典的keys()
方法来遍历字典的所有键。以下是语法和示例:
语法:
python复制代码 dict.keys()
例子:
my_dict = {'name': 'Alice', 'age': 25, 'city': 'New York'} # 遍历字典的所有键 for key in my_dict.keys(): print('Key:', key)
输出:
Key: name Key: age Key: city
在这个例子中,我们使用for
循环和keys()
方法遍历字典my_dict
的所有键,并打印出每个键。
4.5.3.3 遍历字典所有值 dic.values
你可以使用for
循环和字典的values()
方法来遍历字典的所有值。以下是语法和示例:
语法:
python复制代码 dict.values()
例子:
my_dict = {'name': 'Alice', 'age': 25, 'city': 'New York'} # 遍历字典的所有值 for value in my_dict.values(): print('Value:', value)
输出:
Value: Alice Value: 25 Value: New York
在这个例子中,我们使用for
循环和values()
方法遍历字典my_dict
的所有值,并打印出每个值。
4.5.4 字典推导式
你可以使用字典推导式(dictionary comprehension)来创建字典。这是一种简洁的方式,可以快速地从一个或多个键值对生成字典。
基本语法如下:
python复制代码 {key_expression : value_expression for item in iterable}
这里,key_expression
通常是一个变量,value_expression
通常也是一个变量,item
是迭代器中的元素。
例如,从一个包含学生姓名和分数的列表中创建一个字典,其中学生姓名是键,分数是值:
students = [('Alice', 90), ('Bob', 85), ('Charlie', 88)] score_dict = {name : score for name, score in students} print(score_dict) # 输出:{'Alice': 90, 'Bob': 85, 'Charlie': 88}
字典推导式也可以包含过滤条件。例如,只包含分数大于等于85的学生:
score_dict = {name : score for name, score in students if score >= 85} print(score_dict) # 输出:{'Bob': 85, 'Charlie': 88}
选择策略:根据具体需求,结合优缺点,综合考虑
字典:
优点:根据键获取值,读取速度快;代码可读性相对于列表高(根据键获取与根据索引获取)
缺点:内存占用大,获取值只能根据键,不灵活。
列表:
优点:根据索引/切片,获取元素更加灵活。比字典占内存更小。
缺点:通过索引获取,如果信息较多,可读性不高。
字典内嵌列表
语法:
{
"张无忌":[28,100,"男"],
}
作用:你可以创建一个字典,其中键可以是任何不可变类型(如字符串、整数、浮点数、元组等),而值可以是任何Python对象,包括列表。这种字典中内嵌列表的情况叫做字典的值是可变的。
例子:
# 创建一个字典,其中值是列表 my_dict = { 'list1': [1, 2, 3], 'list2': [4, 5, 6], 'list3': [7, 8, 9] } # 修改字典中的列表元素 my_dict['list1'].append(10) print(my_dict) # 输出: {'list1': [1, 2, 3, 10], 'list2': [4, 5, 6], 'list3': [7, 8, 9]}
在这个例子中,我们创建了一个字典my_dict
,它的值是三个列表。然后我们向'list1'中添加了一个新元素10。可以看到,我们修改的是字典中的列表,而不是字典本身。这种修改不会影响到字典的其他部分。
同样地,你也可以在已有的列表基础上创建新的列表,然后将它们作为字典的值。例如:
# 创建一个字典,其中值是新的列表 my_dict = { 'new_list1': [1, 2, 3], 'new_list2': [4, 5, 6], 'new_list3': [7, 8, 9] } # 创建一个新的列表,并将其作为字典的值 my_dict['new_list3'] += [10, 11] print(my_dict) # 输出: {'new_list1': [1, 2, 3], 'new_list2': [4, 5, 6], 'new_list3': [7, 8, 9, 10, 11]}
在这个例子中,我们首先创建了一个字典my_dict
,它的值是三个新列表。然后我们创建了一个新的列表[10, 11]
,并将其添加到了'new_list3'的尾部。可以看到,我们修改的是字典中的列表,而不是字典本身。这种修改不会影响到字典的其他部分。
列表内嵌字典
语法:
[
{"name":"张无忌","ago":28,"score":"100","sex":"男"}
]
列表内嵌列表
[
["张无忌",28,100,男],
]
字典内嵌字典
{
"张无忌":{"age":28,"score":100,"sex":"男"},
}
练习1,在控制台中录入多个人的多个喜好,
例如请输入姓名:请输入第一个喜好:请输入第二个喜好
5. 函数
5.1 函数的定义
函数的定义使用def
关键字,
语法:
def function_name(arguments): # 函数体 # 这里可以执行一些操作,并返回结果 return result
其中,function_name
是函数的名称,可以自定义,但最好使用有意义的名称以便于阅读和理解代码;arguments
是函数的参数列表,可以包含多个参数,多个参数之间使用逗号分隔;result
是函数返回的结果。
例子:
def add(a, b): result = a + b return result
这个函数接受两个参数a
和b
,将它们相加并返回结果。可以通过调用这个函数来获取结果。例如:
x = 3 y = 5 z = add(x, y) # 调用add函数,并将结果保存到变量z中 print(z) # 输出8,即x和y的和
5.2 函数的参数
def fun01(a,b,c,d): print(a) print(b) print(c) print(d) #位置实参:实参与形参根据位置依次对应, fun01(1,2,3,4) #关键字形参:实参与形参根据名称进行对应 fun01(a = 9 ,d = 3 ,c = 7 ,b = 7) list01 = ["a","b","c","d"] #序列实参:星号将序列拆封后按照位置与形参对应 输入位置实参的一种 #如果参数多,可以存储在序列中(字符串/列表/元组)中,通过拆分,直接传入函数 fun01(list01) #字典实参:双星号将字典拆分后按照名称与形参进行对应 #与序列的好处相同,优点是可以改变顺序,通过拆分 dict01 = {"a":1,"c":3,"d":4 , "b":2} fun01(dict01) """ 函数参数 形式参数 """ #缺省(默认)参数:如果参数不提供,可以使用默认值。 #关键字实参 + 缺省形参 :调用者可以随意传递参数 def fun02(a = 0,b = 0,c = 0,d = 0): print(a) print(b) print(c) print(d) fun01(b=2,c=2) #练习 :定义函数,根据小时,分钟,秒,计算总秒数, #要求:可以计算小时————》秒 #可以只计算分钟————》秒 #可以只计算小时+分钟——————》秒 #可以只计算小时+秒————》秒 def fun03(hour = 0,minute = 0,second = 0): hour * 3600 + minute * 60 + second print(fun03(1,1,1)) print(fun03(hour=1)) print(fun03(hour=1,second=2)) print(fun03(2,3)) print(fun03(minute=1,second=1)) #星号元组形参:* 将所有实参合并为一个元组 #作用:让实参个数无限,一般用args def fun01(args): print(args) fun01() fun01(1) fun01(1,"2") fun01(1,2,3,4,5,6) #练习:定义函数,数值相加的函数, def fun02(arges): return sum(arges) fun02(1,2,3,4) fun02(2,4,6,7,) #4.命名关键字形参:在星号元组形参以后的位置形参 #目的:要去实参必须使用关键字实参, def fun04(a,arges,b): print(a) print(arges) print(b) fun04(1,b = 6) fun04(1,2,3,4,b = 7) def fun05(,a,b): print(a) print(b) fun05(a = 1, b = 2) #5,双星号字典形参:实参可以传递数量无限的关键字实参 #的目的可以将实参合并为字典 def fun06(a): print(a) fun06(a = 1,b = 2)
形参(Parameter)是指在定义函数或方法时,列在括号中的变量名,函数/方法在被调用的时候才会传递给它们具体的值,这种值被称为实参(Argument)。
形参和实参的主要区别在于它们的作用时机和作用对象。形参是在函数/方法定义时定义的,而实参是在函数/方法调用时传递的。形参的作用是接收实参的值,并在函数/方法内部使用。实参可以是任何有效的Python数据类型。
例子:
def add(a, b): return a + b # 调用add函数时,传递了两个实参1和2 result = add(1, 2) print(result) # 输出3
在这个例子中,a
和b
都是形参,它们在add
函数的定义中被定义。在调用add
函数时,我们传递了两个实参1和2。函数内部使用形参a
和b
接收这两个实参的值,并返回它们的和。
5.3.函数的返回值
语法:函数可以通过return
语句返回值。返回值可以是任何有效的Python数据类型,例如整数、浮点数、字符串、列表等。
作用:是向调用方传递函数的结果,以便在程序的其他部分中使用。
例子:
# 定义一个函数,计算两个数的和并返回结果 def add(a, b): sum = a + b return sum # 调用add函数,并将返回值保存到变量result中 result = add(3, 5) print(result) # 输出8
在上面的例子中,add
函数接收两个参数a
和b
,计算它们的和,并通过return
语句返回结果。在调用add
函数时,我们将返回值保存到变量result
中,并在控制台打印出结果。
需要注意的是,return
语句在函数中的位置非常关键,它决定了函数的返回值。如果在函数执行过程中遇到return
语句,那么函数将立即结束并返回return
语句后的值。如果函数中没有return
语句或者return
语句后没有指定任何值,那么函数将返回None
。
此外支持多条return
语句,可以通过判断条件来决定返回哪个值。例如:
def max(a, b): if a > b: return a else: return b result = max(3, 5) print(result) # 输出5
在上面的例子中,max
函数通过判断条件来决定返回两个数中的较大值。
5.4 函数的说明文档
作用:你可以使用docstrings来为函数编写说明文档。
语法:docstrings是一种特殊的注释格式,它可以让你在函数上方使用三引号(""" 或 ''')来编写多行注释,以描述函数的作用、参数、返回值等信息。
例子:
def sum_numbers(num1, num2): """ 计算两个数的和并返回结果。 参数: num1 (int): 第一个整数参数。 num2 (int): 第二个整数参数。 返回值: int: 两个参数的和。 示例: result = sum_numbers(3, 5) # 返回值是8 注意事项: * 输入参数必须为整数类型。 * 如果输入参数不是整数类型,函数将抛出TypeError异常。 * 如果输入参数为负数,函数将抛出ValueError异常。 """ # 函数实现部分,计算两个数的和并返回结果 return num1 + num2
在这个示例中,我们使用了四个部分来编写函数的docstring:
-
函数的作用(计算两个数的和并返回结果)。
-
输入参数(num1和num2,类型为整数)。
-
返回值(两个参数的和,类型为整数)。
-
示例代码和注意事项(输入参数必须为整数类型,如果输入参数不是整数类型或为负数,函数将抛出异常)。
你可以使用Python的帮助文档(使用help()
函数)或使用IDE的自动补全功能来查看函数的docstring,以方便其他开发人员使用和理解你的函数。
5.5 函数的嵌套
语法:函数的嵌套指的是在一个函数内部定义另一个函数。这种结构在编程中很有用,它可以帮助组织代码,使其更易于阅读和维护。
嵌套函数:
def outer_function(x): """外部函数""" def inner_function(y): """内部函数""" return x + y return inner_function # 调用外部函数并获取内部函数 nested_function = outer_function(10) # 使用内部函数 result = nested_function(5) print(result) # 输出 15
在这个示例中,outer_function
是一个外部函数,它接受一个参数x
。在outer_function
内部,我们定义了一个内部函数inner_function
,它接受一个参数y
,并返回x + y
的结果。通过调用outer_function(10)
,我们获取到内部函数,并存储在nested_function
变量中。然后,我们可以使用nested_function(5)
来计算结果。
嵌套函数的作用主要有以下几点:
-
代码组织和模块化:通过将一些相关的代码块放在一起,并通过函数名进行封装,可以使代码更加清晰和易于理解。同时,这也使得代码更易于复用和模块化。
-
逻辑复用:如果在多个地方需要执行相同的计算或操作,可以通过定义嵌套函数,然后在需要的地方进行调用,从而避免代码重复。
-
参数传递和闭包:嵌套函数可以访问其外部函数的变量,这就使得它们可以用于创建闭包和高阶函数等更复杂的编程概念。这种能力使得嵌套函数在处理一些复杂逻辑时非常有用。
5.6 变量的作用域
在Python中,变量的作用域可以通过一些特定的语法来定义和控制。下面是一些关于Python变量作用域的语法、作用和例子:
-
全局变量和局部变量
语法:
全局变量在函数外定义,局部变量在函数内定义。
作用:
全局变量在整个程序中都是可见的,而局部变量只在定义它的函数内部可见。
例子:
# 全局变量 x = 10 def my_function(): # 局部变量 y = 20 print("Inside function:", x, y) # 可以访问全局变量x和局部变量y print("Outside function:", x) # 只能访问全局变量x my_function()
-
global
和nonlocal
关键字
语法:
使用global
关键字可以在函数内部修改全局变量。使用nonlocal
关键字可以在嵌套函数中修改外部函数的局部变量。
作用:
这两个关键字允许你修改不在当前作用域内的变量。
例子:
# global 关键字示例 x = 10 # 全局变量 def my_function(): global x # 声明要使用的全局变量x x = x * 2 # 修改全局变量x的值 print("Inside function:", x) # 输出20 my_function() print("Outside function:", x) # 输出20,因为全局变量x的值已被修改
-
LEGB规则(Local, Enclosing, Global, Built-in)
Python按照LEGB规则来搜索变量的值。简单地说,Python首先在当前作用域(Local)中查找变量,如果找不到,则到包含函数的作用域(Enclosing)中查找,然后到全局作用域(Global)中查找,最后到内置作用域(Built-in)中查找。这个规则帮助你理解Python如何在不同作用域之间查找变量。
-
闭包(Closure)和嵌套函数(Nested Function)中的作用域
在嵌套函数中,内部函数可以访问外部函数的变量,即使外部函数已经执行完毕。这就是闭包的概念。闭包允许你“记住”嵌套函数被创建时的环境。这在很多情况下非常有用,例如隐藏实现细节或创建具有状态的函数等。以下是一个简单的例子:
例子:
def outer_function(x): # 外部函数,有一个参数x def inner_function(y): # 内部函数,有一个参数y return x + y # 内部函数可以访问外部函数的变量x和自身的变量y return inner_function # 返回内部函数,形成一个闭包
在这个例子中,inner_function
可以访问其外部函数outer_function
的变量x
。这种能力使得嵌套函数在处理一些复杂逻辑时非常有用。例如,你可以通过调用outer_function(10)
来获取一个新的函数,该函数会将传入的值加上10。
5.7 函数的多返回值
作用:函数可以通过返回元组(tuple)的方式来返回多个值。元组是一个不可变的序列类型,可以包含不同类型的元素。
例子:
def calculate_area_and_perimeter(radius): area = 3.14 * radius ** 2 perimeter = 2 * 3.14 * radius return area, perimeter area_and_perimeter = calculate_area_and_perimeter(5) area, perimeter = area_and_perimeter print("Area:", area) print("Perimeter:", perimeter)
在这个例子中,函数 calculate_area_and_perimeter
接受一个半径作为参数,并计算圆的面积和周长。它使用 return
语句返回一个包含两个元素的元组 (area, perimeter)
。然后,我们可以将这个元组赋值给一个变量 area_and_perimeter
。接下来,我们使用多个变量来解包这个元组,将面积和周长分别赋值给变量 area
和 perimeter
。最后,我们打印出这两个变量的值。
需要注意的是,在函数中使用多个变量来接收返回值时,必须将它们放在同一行上,并使用逗号分隔。例如:
python result1, result2, result3 = some_function()
这将把函数 some_function()
返回的三个值分别赋值给变量 result1
、result2
和 result3
。
5.8 函数作为参数传递
作用:函数作为参数传递是指在一个函数内部调用另一个函数,并将该函数作为参数传递给主调函数。在程序中,函数作为参数传递的方式非常常见,它可以帮助我们实现代码的复用和模块化。
例子:
def add(x, y): return x + y def multiply(x, y): return x * y def calculate(operation, x, y): if operation == "add": return add(x, y) elif operation == "multiply": return multiply(x, y) else: print("Invalid operation") return None result = calculate("add", 2, 3) print(result) # 输出 5
在这个例子中,我们定义了两个函数 add
和 multiply
,分别用于加法和乘法运算。然后,我们定义了一个函数 calculate
,它接受一个操作函数和两个整数作为参数,并根据操作函数的类型执行相应的计算。在本例中,我们将 add
和 multiply
函数作为参数传递给 calculate
函数,并在其中使用这些函数进行计算。最后,我们将计算结果赋值给变量 result
并打印出来。
需要注意的是,在将函数作为参数传递时,需要确保传递的函数是可调用的,否则将会引发类型错误。此外,我们还可以使用可迭代对象(如列表、元组等)来传递多个函数参数。
5.9 lambda匿名函数
定义:这是一种匿名方法
语法:lambda 形参:方法体
注意:方法体只有一条语句,且不支持赋值语句
def fun01(): return 100 a = lambda :100 re = a() print(re) def fun02(p1,p2): return p1 > p2 b = lambda p1,p2:p1 > p2 re = b(1,2) print(re) def fun03(p1): print("参数是",p1) c = lambda p1:print("参数是",p1) c(100) #需求1:技能列表中名称大于4个字的技能数量 #需求2:技能列表持续时间销毁5的技能数量 class SkillData: def __init__(self,name,id,age,cond): self.id = id self.age = age self.name = name self.cond = cond list02 = [ SkillData(101,"乾坤大挪移",5,10), SkillData(102,"降龙18掌",8,5), SkillData(103,"葵花宝典",10,2), ]
小游戏2048核心算法
""" 2048游戏核心算法 """ #1.零元素移动到末尾 #[2,0,2,0] ----> [2,2,0,0] #[2,0,0,2]---->[2,2,0,0] #[2,4,0,2]————》[2,4,2,0] list_merge = [2,0,2,0] def zero_to_end(): """ 零元素移动到末尾 :return: """ #思想:从后向前,如果发现零元素,删除并追加 for i in range(-1,-len(list_merge)-1,-1): if list_merge[i] == 0: del list_merge[i] list_merge.append(0) #zero_to_end() #print(list_merge) #练习二相同数字合并 #[2,0,2,0] ----> [4,0,0,0] #[2,0,0,2]---->[4,0,0,0] #[2,4,0,2]————》[2,4,2,0] #【2,2,2,2】 ——————》[4,4,0,0] # [2,2,2,0] ----->[4,2,0,0] def marge(): """ 合并 :return: """ #先将中间的零元素移到末尾 #在合并相同元素 zero_to_end() for i in range(len(list_merge)-1): if list_merge[i] == list_merge[i+1]: #将后一个累加前一个之上 list_merge[i] += list_merge[i+1] del list_merge[i+1] list_merge.append(0) #marge() #print(list_merge) #练习三地图向左移动 map = [ [2,0,0,2], [4,4,2,2], [2,4,0,4], [0,0,2,2], ] def move_left(): """ 向左移动 :return:将二维码中每行交给merge函数进行操作 """ for line in map: global list_merge list_merge = line marge() #右移动 def move_right(): """ 向右移动,将二维列表每行(从右向左)交给merge函数进行操作 :return: """ for line in map: global list_merge #从右向左取出数据形成新列表 list_merge = line[::-1]#切片创造一个新的列表 marge() #从右向左接收 合并后的数据 line[::-1] = list_merge #练习四上移动,下移动 #利用方阵转置函数 def move_up(): square_matrix_transpose(map) move_left() square_matrix_transpose(map) def square_matrix_transpose(sqr_matrix): n = len(sqr_matrix) for i in range(n): for j in range(i+1, n): sqr_matrix[j][i], sqr_matrix[i][j] = sqr_matrix[i][j], sqr_matrix[j][i] return sqr_matrix def move_down(): square_matrix_transpose(map) move_right() square_matrix_transpose(map) move_down() print(map)
关于2048综合知识
""" 游戏逻辑控制器,负责处理游戏核心算法 """ class GameCoreController: def __init__(self): self.__list_merge = None self.__map = [ [2,0,0,2], [4,4,2,2], [2,4,0,4], [0,0,2,2], ] @property def map(self): return self.__map def __zero_to_end(self): """ 零元素移动到末尾 :return: """ # 思想:从后向前,如果发现零元素,删除并追加 for i in range(-1, -len(self.__list_merge) - 1, -1): if self.__list_merge[i] == 0: del self.__list_merge[i] self.__list_merge.append(0) def __marge(self): """ 合并 :return: """ # 先将中间的零元素移到末尾 # 在合并相同元素 self.__zero_to_end() for i in range(len(self.__list_merge) - 1): if self.__list_merge[i] == self.__list_merge[i + 1]: # 将后一个累加前一个之上 self.__list_merge[i] += self.__list_merge[i + 1] del self.__list_merge[i + 1] self.__list_merge.append(0) def move_left(self): """#global list_merge,原来是想修改全局变量,而现在不用修改 向左移动 :return:将二维码中每行交给merge函数进行操作 """ for line in self.__map: self.__list_merge = line self.__marge() def move_right(self): """ 向右移动,将二维列表每行(从右向左)交给merge函数进行操作 :return: """ for line in self.__map: # 从右向左取出数据形成新列表 self.__list_merge = line[::-1] # 切片创造一个新的列表 self.__marge() # 从右向左接收 合并后的数据,此时通过切片定位元素 line[::-1] = self.__list_merge # 练习四上移动,下移动 # 利用方阵转置函数 def move_up(self): self.square_matrix_transpose() self.__move_left() self.__square_matrix_transpose() def move_down(self): self.__square_matrix_transpose() self.move_right() self.__square_matrix_transpose() def __square_matrix_transpose(self): for c in range(1,len(self.__map)): for r in range(c,len(self.__map)): self.__map[r][c-1],self.__map[c-1][r] = self.__map[c-1][r],self.__map[r][c-1] def move(self,qtx): if qtx : #-----------测试代码----- if __name__ == "__main__": first01 = GameCoreController() first01.move_left() print(first01.map)
列表助手类
class ListHelper: @staticmethod def find_all(lst, condition): """ 返回列表中满足条件的所有元素组成的新列表 """ return [item for item in lst if condition(item)]
@staticmethod def find_single(lst, condition): """ 返回列表中满足条件的第一个元素 """ for item in lst: if condition(item): return item return None @staticmethod def count(lst, condition): """ 返回列表中满足条件的元素个数 """ return len([item for item in lst if condition(item)]) @staticmethod def get_count(lst, condition): """ 返回列表中满足条件的元素个数 """ return sum(1 for item in lst if condition(item)) @staticmethod def is_exists(lst, condition): """ 判断列表中是否存在满足条件的元素 """ return any(condition(item) for item in lst) @staticmethod def remove_all(lst, condition): """ 移除列表中满足条件的所有元素 """ return [item for item in lst if not condition(item)]
示例用法
if name == "main": list01 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 找出所有偶数 evens = ListHelper.find_all(list01, lambda x: x % 2 == 0) print("偶数列表:", evens) # 找出第一个大于5的元素 first_gt_5 = ListHelper.find_single(list01, lambda x: x > 5) print("第一个大于5的元素:", first_gt_5) # 统计大于5的元素个数 count_gt_5 = ListHelper.count(list01, lambda x: x > 5) print("大于5的元素个数:", count_gt_5) # 使用 get_count 方法统计大于5的元素个数 count_gt_5_v2 = ListHelper.get_count(list01, lambda x: x > 5) print("大于5的元素个数(v2):", count_gt_5_v2) # 判断是否存在大于10的元素 exists_gt_10 = ListHelper.is_exists(list01, lambda x: x > 10) print("是否存在大于10的元素:", exists_gt_10) # 移除所有偶数 list02 = ListHelper.remove_all(list01, lambda x: x % 2 == 0) print("移除偶数后的列表:", list02)
python中内置高阶函数
#内置高阶函数 class Enemy: def __init__(self,name,hp,atk,defense): self.name = name self.hp = hp self.atk = atk self.defense = defense def __str__(self): return "%s--%d---%d--%d" % (self.name, self.hp, self.atk, self.defense) list01 = [ Enemy("玄冥二老",86,120,58), Enemy("成昆",0,100,5), Enemy("谢逊",120,130,60), Enemy("灭霸",0,1309,690), ] #需求获取所有死人 re = filter(lambda item:item.hp == 0,list01) print(re) #------------------------ for item in re: print(item) """ filter(函数,可迭代对象):根据条件筛选可迭代对象中氮元素,返回值为新可迭代对象 """ #需求获取所有敌人的姓名 huoqu01 = map(lambda item:item.name,list01) for item in huoqu01 : print(item) """ map:使用可迭代对象中的每一个元素调用函数,将返回值作为新可迭代对象,返回值为新可迭待对象。 通用的筛选方法 """ #获取所有血量最大的敌人 print( max(list01,key=lambda item:item.hp) ) """ max:获取最大值 需求:获取血量最大的敌人 """ #获取血量最少的敌人 print(min(list01,key=lambda item:item.hp)) """ min:获取最小值 """ #排序 #内部直接修改返回值,使用时无需通过返回值修改数据 #内部返回新列列表,使用时必须返回返回值,并且可以支持降序排序 sorted(list01,key=lambda item:item.atk) for item in list01: print(item) sorted(list01,key=lambda item:item.atk,reverse=True) for item in list01: print(item) """sorted() 函数会返回一个新的排好序的列表,但并不会修改原始列表 list01。 因此,如果你想在后续的操作中使用排序后的列表,需要将返回值保存到一个变量中,或者直接使用返回值。 "
内置高阶函数与列表助手之间的区别:对于简单的列表操作和小规模数据,可以选择列表助手类;而对于复杂的操作和大规模数据,使用内置高阶函数可能更合适。
#获取元组中长度最大的列表 tuple01 = ([1,1,1],[2,2],[3,3,3,3]) print(max(tuple01,key=lambda item:len(item))) #练习,生成器 list02 = ("猪八戒","孙悟空","唐僧") list03 = (110,120,130) def my_zeip(list01,list02): for i in range(len(list01)): yield (list01[i],list02[i]) for item in my_zeip(list02,list03): print(item) #2,根据敌人列表,获取所有敌人的姓名与血量以及攻击力 class Enemy: def __init__(self,name,hp,atk,defense): self.name = name self.hp = hp self.atk = atk self.defense = defense def __str__(self): return "%s--%d---%d--%d" % (self.name, self.hp, self.atk, self.defense) list01 = [ Enemy("玄冥二老",86,120,58), Enemy("成昆",0,100,5), Enemy("谢逊",120,130,60), Enemy("灭霸",0,1309,690), ] re = map(lambda item:(item.name,item.hp,item.atk,item.defense),list01) for item in re: print(item) #在敌人列表中,获取攻击力大于100的所有活人 re = filter(lambda item:item.atk > 100 and item.hp > 0,list01) for i in re: print(i) #防御力大于100的人 s01 = sorted(list01,key=lambda item: item.atk ,reverse = True) for i in s01: print(i) """ 外部嵌套作用域 """ def fun01(): #是fun01的局部句作用域 #是fun02函数的外部嵌套作用域 a = 1 def fun02(): #global b = 2 #可以访问外部嵌套作用域变量 # print(a) #a = 2#创建了fun02的局部变量 #print(a)#2 nonlocal a#声明外部嵌套作用域 a = 2 print(a) fun02() print(a)#1 fun01()
6. 模块及常用库
6.1 导入语句
6.1.1 import 语句
导入方式1
语法:import 需要调用的py文件
如果模块名起冲突更改方式:import 模块名 as 别名
(如果想要调用py文件在同一个文件夹中则右键这同一个文件夹,找到Mare directory as---->sources Root
无论用import调用多少次同一个模块自上而下都只运行一次关于这个模块)
module01.py的文件
print("模块一") def fun01(): print("模块一中的fun01") class MyClass02: def fun02(self): print("MyClass02 -- fun02"
import module01 module01.fun01() my02 = module01.MyClass02()#它是一个实例对象所以不能直接用 my02.fun02()
调用并且进行
6.1.2 from…import 语句
导入方式2(就近原则:导入进来的成员不要与当前模块成员冲突)
语法:from 模块 import 模块里的东西
如果模块名起冲突更改方式:from 模块名 import 成员名 [as 别名 1]
导入进来可以直接用,只调用模块的特定部分本质:将指定的成员导入当前模块的作用域中
print("模块一") def fun01(): print("模块一中的fun01") class MyClass02: def fun02(self): print("MyClass02 -- fun02")
from module01 import fun01 from module01 import MyClass02 fun01() m02 = MyClass02() m02.fun02()
6.1.3 from…import* 语句
导入方式3
本质:将指定模块的所有成员导入到当前模块的作用域中
注意;小心导入进来的与其他模块冲突
print("模块一") def fun01(): print("模块一中的fun01") class MyClass02: def fun02(self): print("MyClass02 -- fun02")
from module01 import * fun01() x02 = MyClass02() my02.fun02()
模块中以下划线(_)开头的属性,不会被导入,通常称这些成员为隐藏成员,一般来说只在模块内部使用的成员可以以单下划线开头。
from module01 import * fun01() #隐藏成员,不能通过from模块import*导入 _fun02() from module01 import _fun02 例如如果使用from 模块 import *调用_fun02调用不出来但是如果使用from 模块 import _fun02就可以调用
模块变量
1,all变量:定义可导出成员,仅对from 模块 import *语句有效
__all__ = ["fun01","需要调用的",""]
2,doc变量:文档字符串
print(__doc__)
3,file变量:模块对应的文件路径名
print(__file__)
4,name变量:
主模块(第一个运行的模块)叫做:main,非主模块叫做:真名
print(__name__)
作用:测试代码,只有从当前模块运行才会执行。
只有是主模块才执行
包
定义:包(Package)是一种组织和管理模块的方式,它将相关的模块组织在一起形成一个文件夹,这个文件夹内还包含一个特殊的文件 __init__.py
,表示这个文件夹是一个包。
例子:
-
包的创建:
-
在包的文件夹内创建一个
__init__.py
文件。 -
将相关的模块放置在包的文件夹内。
例如,如果我们有一个名为
my_package
的包,文件结构如下:markdownCopy codemy_package/ ├── __init__.py ├── module1.py └── module2.py
-
-
包的导入:
-
使用
import
语句导入整个包或包内的模块。
pythonCopy codeimport my_package from my_package import module1
-
其中all在init的作用
在一个包的 __init__.py
文件中,你可以使用 __all__
来明确指定哪些模块应该被导入,而不是导入整个包。这对于控制包的公共接口很有用。
以下是一个简单的例子:
pythonCopy code# __init__.py __all__ = ['module1', 'module2'] from . import module1 from . import module2
迭代
迭代原理:for循环的原理是什么?获取迭代器,循环获取下一个对象。遇到异常自动停止循环
可以被for的条件是什么?能被for的对象必须具备——iter——方法
list01 = [3,23,43,21,321] for item in list01: print(item) #原理 #获取迭代器 iterator = list01.__iter__() #循环获取下一个元素 while True: try: item = iterator.__next__() print(item) #遇到异常停止迭代 except StopIteration: break#退出循环
内置模块
内置高阶模块
-
作用:内置模块是Python标准库中预先定义好的模块,包含了各种功能丰富、常用的工具和函数,用于解决各种常见的问题。这些模块可以直接在Python中使用,无需额外安装,例如
datetime
、random
、os
、math
等。 -
语法:使用内置模块需要先导入模块,然后通过模块名来调用其中的函数或类。例如:
import datetime
,now = datetime.datetime.now()
。 -
例子:使用
random
模块生成随机数,使用os
模块进行文件操作,使用math
模块进行数学运算等。
#内置高阶函数 class Enemy: def __init__(self,name,hp,atk,defense): self.name = name self.hp = hp self.atk = atk self.defense = defense def __str__(self): return "%s--%d---%d--%d" % (self.name, self.hp, self.atk, self.defense) list01 = [ Enemy("玄冥二老",86,120,58), Enemy("成昆",0,100,5), Enemy("谢逊",120,130,60), Enemy("灭霸",0,1309,690), ] #需求获取所有死人 re = filter(lambda item:item.hp == 0,list01) print(re) #------------------------ for item in re: print(item) """ filter(函数,可迭代对象):根据条件筛选可迭代对象中氮元素,返回值为新可迭代对象 """ #需求获取所有敌人的姓名 huoqu01 = map(lambda item:item.name,list01) for item in huoqu01 : print(item) """ map:使用可迭代对象中的每一个元素调用函数,将返回值作为新可迭代对象,返回值为新可迭待对象。 通用的筛选方法 """ #获取所有血量最大的敌人 print( max(list01,key=lambda item:item.hp) ) """ max:获取最大值 需求:获取血量最大的敌人 """ #获取血量最少的敌人 print(min(list01,key=lambda item:item.hp)) """ min:获取最小值 """ #排序 #内部直接修改返回值,使用时无需通过返回值修改数据 #内部返回新列列表,使用时必须返回返回值,并且可以支持降序排序 sorted(list01,key=lambda item:item.atk) for item in list01: print(item) sorted(list01,key=lambda item:item.atk,reverse=True) for item in list01: print(item) """sorted() 函数会返回一个新的排好序的列表,但并不会修改原始列表 list01。 因此,如果你想在后续的操作中使用排序后的列表,需要将返回值保存到一个变量中,或者直接使用返回值。 """
6.2 自定义模块
-
作用:自定义高阶模块是开发者根据自己的需求自行编写的模块,其中包含了特定功能或工具函数。这些模块可以根据项目的需求进行定制,提供更灵活、更专业的解决方案。
-
语法:编写自定义高阶模块需要创建一个
.py
文件,在其中定义函数、类或变量,并且可以使用import
导入到其他文件中使用。例如:import my_module
。 -
例子:编写一个自定义的日志模块,包含了记录日志、保存日志到文件、设置日志级别等功能;编写一个自定义的数据处理模块,包含了数据清洗、转换、分析等功能。
例子:
class List_help: @staticmethod def find_single(lst, condition): """ 返回列表中满足条件的第一个元素 """ for item in lst: if condition(item): return item return None @staticmethod def count(lst, condition): """ 返回列表中满足条件的元素个数 """ return len([item for item in lst if condition(item)]) @staticmethod def get_count(lst, condition): """ 返回列表中满足条件的元素个数 """ return sum(1 for item in lst if condition(item)) @staticmethod def is_exists(lst, condition): """ 判断列表中是否存在满足条件的元素 """ return any(condition(item) for item in lst) @staticmethod def remove_all(lst, condition): """ 移除列表中满足条件的所有元素 """ return [item for item in lst if not condition(item)] #在敌人列表中,删除所死人 #获取最小值 # # """ 复习 函数作为参数 定义高阶函数:list_help.py 内置高阶函数: map (函数,可迭代对象) ------》 list_help.select fileter (函数,可迭代对象)------》list_help.find-all max(可迭代对象,key = 函数)--------->list_help.get_max main(可迭代对象,key = 函数) --------> list_help sorted(可迭代对象 , key = 函数)-------->list_help.order_by sorted(可迭代对象 , key = 函数)----------->list_help 函数作为返回值 """ @staticmethod def get_min(list_target,func_handle): """ 通用调取最小元素的方法 :param list_target:需要搜索的列表 :param func_handle: 需要搜索处理罗杰,函数类型 函数名(参数) ---》 int/str/...... :return: 最小元素 """ min_value = list_target[0] for i in range(1,len(list_target)): if func_handle(min_value) > func_handle(list_target[i]): min_value = list_target[i] return min_value @staticmethod # def order_by_descending(list_target,func_handle): # """ # 通过降序的拍排列方法 # :param list_target:需要排列的数据 # :param func_handle:排列的逻辑 # 函数(参数) ——————》int/float...需要比较的数据 # :return: # """ # for r in range(len(list_target)-1): # for c in range(r+1,len(list_target)): # if func_handle(list_target[r]) < func_handle(list_target[c]): # list_target[r],list_target[c] = list_target[c] ,list_target[r] def order_by_descending(list_target, func_handle): """ 通过降序的排列方法 :param list_target: 需要排列的数据 :param func_handle: 排列的逻辑函数 :return: None """ for r in range(len(list_target) - 1): for c in range(r + 1, len(list_target)): if func_handle(list_target[r]) < func_handle(list_target[c]): list_target[r], list_target[c] = list_target[c], list_target[r] # 示例数据 list01 = [100, 43, 23324, 534, 121, 76, 98, 433, 2, 3, 6, 7] # 使用函数式编程方式进行降序排列 order_by_descending(list01, lambda item: item) print(list01) # 输出排序后的列表
# mymodule.py def greet(name): return f"Hello, {name}!" def add(a, b): return a + b
pythonCopy code# main.py import mymodule name = "Alice" result = mymodule.greet(name) print(result) sum_result = mymodule.add(3, 5) print(sum_result)
内置模块,与自定义高阶模块的比较
内置模块是Python语言提供的标准库,可以直接使用解决常见问题;而自定义高阶模块则是根据具体需求开发者自行编写的,可以提供更专业、更灵活的功能。在实际开发中,通常会同时使用内置模块和自定义高阶模块来完成项目的开发任务。
6.3 第三方模块(库)
6.3.1 第三方模块下载
-
通过 pip 安装单个库
打开终端(命令提示符或终端窗口)并执行以下命令:
bashCopy code pip install library_name
例如,安装
requests
库:bashCopy code pip install requests
-
通过 requirements.txt 安装多个库
创建一个名为
requirements.txt
的文本文件,其中列出了你要安装的库及其版本号,每行一个库。例如:makefileCopy coderequests==2.26.0 numpy==1.21.2 pandas==1.3.3
然后,在终端执行以下命令:
bashCopy code pip install -r requirements.txt
这
将安装文件中列出的所有库及其指定的版本。
-
从 GitHub 安装库
如果库的源代码托管在 GitHub 上,你可以使用
pip
直接从 GitHub 安装:bashCopy code pip install git+https://github.com/username/repo.git
或者,你也可以通过在
requirements.txt
文件中添加相应的行来实现:arduinoCopy code git+https://github.com/username/repo.git
-
从本地文件安装库
如果你有一个本地的库文件(通常是以
.tar.gz
或.zip
格式压缩的),你可以使用以下命令进行安装:bashCopy code pip install path/to/local/file.tar.gz
或
bashCopy code pip install path/to/local/file.zip
这将安装你指定的本地库文件。
-
使用 conda 安装
如果你使用了 Anaconda 或 Miniconda,可以使用
conda
来安装库:bashCopy code conda install library_name
请注意,
conda
是一个针对数据科学和机器学习领域的包管理器。
这些是一些常见的第三方库安装方法。具体的安装方法和使用说明可以在每个库的官方文档中找到。
6.3.2 导入第三方库
6.3.3 常见的库
6.3.3.1 datetime(自带)
6.3.3.2 random(自带)
6.3.3.3 jieba(需下载)
6.3.3.4 math(自带)
7. 文件操作
7.1 编码概念
7.2 文件操作
-
打开文件:
使用
open()
函数打开文件,可以指定文件名和打开模式(读取、写入、追加等)。pythonCopy code# 打开文件并读取内容 with open('example.txt', 'r') as file: content = file.read() print(content) # 打开文件并写入内容 with open('example.txt', 'w') as file: file.write('Hello, World!')
-
读取文件:
使用文件对象的
read()
方法来读取文件内容。pythonCopy codewith open('example.txt', 'r') as file: content = file.read() print(content)
-
逐行读取文件:
使用文件对象的
readline()
方法逐行读取文件内容。pythonCopy codewith open('example.txt', 'r') as file: line = file.readline() while line: print(line.strip()) # 去除换行符 line = file.readline()
-
写入文件:
使用文件对象的
write()
方法写入内容到文件。pythonCopy codewith open('example.txt', 'w') as file: file.write('Hello, World!')
-
追加内容到文件:
使用文件对象的
a
模式来追加内容到文件。pythonCopy codewith open('example.txt', 'a') as file: file.write('\nAppended Content')
-
遍历文件内容:
使用
for
循环遍历文件对象,逐行处理文件内容。pythonCopy codewith open('example.txt', 'r') as file: for line in file: print(line.strip())
-
异常处理:
在文件操作中,可能会涉及到异常,例如文件不存在、权限问题等,因此需要使用异常处理。
pythonCopy codetry: with open('example.txt', 'r') as file: content = file.read() print(content) except FileNotFoundError: print('文件不存在') except PermissionError: print('没有权限访问文件')
这些是文件操作的基本示例,根据具体需求,可以选择适当的打开模式和方法来进行文件的读写操作。同时,为了确保文件在使用完毕后正确关闭,可以使用 with
语句,它会在离开 with
代码块时自动关闭文件。
7.3 os模块
8. 面向对象
8.1 对象的定义
作用:对象是一种数据类型,它是类的实例。类是创建对象的蓝图或模板,它定义了对象的基本结构和行为。
语法如下:
class ClassName: # class body
在这里,“ClassName”是类的名称,类体包含类的属性和方法。
创建类实例(即对象)的基本语法如下:
python object = Class()
在这里,“object”是对象的名称,“Class()”是类的构造函数,用于创建类的实例。
对象的作用主要有以下几点:
-
封装:对象可以将数据和操作封装在一起,形成一个独立的实体。这样可以隐藏数据的细节,只暴露必要的接口。
-
继承和多态:通过类,可以创建子类来继承和扩展已有的对象。多态性则允许使用不同的类对象来执行相同的操作。
-
代码的可重用性:通过创建类,可以定义通用的行为和数据结构,然后在不同的程序中重复使用。
-
易于理解和维护:通过将相关的数据和操作封装在对象中,代码更易于理解和维护。
8.2 类的属性与方法
在Python中,类的属性(Attributes)和方法(Methods)是面向对象编程的两个核心概念。
类的属性:
定义:类的属性也称为类的变量,它们是用来描述类或者类的实例(对象)的特性。这些属性可以是数据属性(如数字、字符串等),也可以是其他类或者类的实例。
语法:类属性通常在类的定义中直接赋值,也可以在类的构造函数 __init__
中定义。
例字:
class MyClass: # 这是一个类属性 my_attribute = "Hello, world!"
在这个例子中,my_attribute
就是一个类属性。
类的方法:
定义:类的方法是一个特殊类型的函数,它的第一个参数总是表示实例自身的引用(通常命名为 self
)。通过类的方法,我们可以定义对象应该具有的行为。
语法:方法可以在类的定义内部直接定义,也可以通过装饰器 @classmethod
或 @staticmethod
定义。
例如:
class MyClass: # 这是一个类方法 def my_method(self): print("Hello, world!")
在这个例子中,my_method
就是一个类方法。当我们创建一个 MyClass
的实例并调用 my_method
时,它就会打印出 "Hello, world!"。
注意,类属性和类方法都可以通过实例来访问,但是修改类属性会影响到该类所有的实例,而调用类方法则会作用于调用该方法的特定实例。
""" class ICBC: total_money = 1000000 def __init__(self,name,money): self.name = name self.money = money ICBC.total_money -= money i01 = ICBC("广渠门支行",100000) i02 = ICBC("陶然亭支行",10000) i03 = ICBC("安徽支行",100000) print("总行还剩下%d钱"%ICBC.total_money) """ # 练习:定义老婆对象 # 定义老婆类,创建三个老婆对象 # 可以通过类变量记录老婆对象个数, # 通过类方法打印老婆对象个数 """ class Wife: count = 0 def __init__(self, name): self.name = name Wife.count += 1 i01 = Wife("小李") i02 = Wife("小王") i03 = Wife("小乔") print(Wife.count) """ class Wife: count = 0 @classmethod def print_count(cls): print("我有%d房"%cls.count) def __init__(self, name): self.name = name Wife.count += 1 i01 = Wife("小李") i02 = Wife("小王") i03 = Wife("小乔") Wife.print_count() class Student: def __init__(self,name,sex,age,score): self.name = name self.sex = sex self.score = score self.age = age def print_self_info(self): print("%s的年龄是%d,成绩是%d,性别是%s"%(self.name,self.sex,self.age,self.score)) class Student: def __init__(self,name,sex,age,score): self.name = name self.sex = sex self.age = age self.score = score list01 = [ Student("赵敏",28,100,"女"), Student("苏大强",68,62,"男"), Student("明玉",30,95,"女"), Student("无忌",29,70,"男"), Student("张三丰",130,96,"男"), ] def find01(): for item in list01: if item.name == "苏大强": return item #return None,可以不用写如果没有找到则会自动返回空函数返回值默认为空 num01 = find01 print(num01.name,num01.age) #类与类的区别在于行为不同 """class 类名: def__init__(self,参数): self.数据1 = 参数 def 方法名称(): 方法体 注意:类名所有单词首字母大写,不需要用下划线将下划线隔开 创建对象 变量名 = 类名(参数) """ """ 创建学生类 --->数据:姓名,成绩,性别,年龄 --->行为:在控制台中打印个人信息的方法 在控制台中循环录入学生信息,,如果是空字符退出 在控制台中输出学生信息 """ class Student: def __init__(self,name,sex,age,score): self.name = name self.sex = sex self.score = score self.age = age def print_self_info(self): print(self.name)
8.3 类和对象
定义:类域对象(Class-level Objects)是一种特殊类型的对象,它们与类本身关联,而不是与类的实例关联。类域对象通常用于实现一些与类本身相关的功能,而不是与类的实例相关的功能。
定义类域对象的关键在于使用类名称后面加上双下划线(init)和一个参数列表,
例子
class MyClass: def __init__(self, arg1, arg2): self.arg1 = arg1 self.arg2 = arg2 @classmethod def class_method(cls, arg): print(f"Class method called with {arg}") @staticmethod def static_method(arg): print(f"Static method called with {arg}")
在上面的例子中,我们定义了一个名为MyClass
的类,它有一个构造函数__init__
,该函数接受两个参数并将它们存储为实例属性。
当然可以。
1. 类方法 (Class Method)
定义和语法:
类方法是通过装饰器@classmethod
进行修饰的方法。它的第一个参数是类本身,通常被命名为cls
,而不是传统的实例方法中的self
参数。
例如:
class MyClass: @classmethod def my_class_method(cls, arg1, arg2): ...
作用:
-
类方法主要被用来修改或访问类级别的属性。
-
由于类方法接收的是类引用而不是实例引用,因此它们可以在不创建类的实例的情况下被调用。
-
它们常常用于工厂模式,即根据某些条件返回类的不同实例。
2. 类对象 (Class-level Objects 或 Class Variables)
定义和语法:
在Python类中,直接在类定义下(而不是在方法或函数内)定义的变量被称为类变量。这些变量被类的所有实例共享。
例如:
class MyClass: my_class_variable = 100 def __init__(self): self.instance_variable = 200
在这里,my_class_variable
是一个类变量,而instance_variable
是一个实例变量。
作用:
-
类变量被类的所有实例共享。这意味着,如果你修改了一个实例中的类变量,那么它在其他所有实例中都会被改变。但直接修改类变量的值则会影响到所有的实例。
-
类变量通常用于存储与该类所有实例相关的常量或配置信息。
-
与实例变量相比,类变量更加节省内存,因为它们只需要存储一份数据,而不是每个实例都存储一份。
总结:类方法和类对象在Python的面向对象编程中都扮演着重要的角色。类方法提供了一种在不创建类的实例的情况下访问和修改类属性的机制,而类对象则为类的所有实例提供了一个共享的数据存储空间。
8.4 构造方法
定义:构造方法是一种特殊的方法,用于在创建对象时进行初始化。构造方法的名称必须是__init__
,并且它带有至少一个参数,即self。self参数是一个对实例对象的引用,可以在构造方法中使用它来访问实例的属性。
例子,演示了如何在Python中定义构造方法:
class MyClass: def __init__(self, arg1, arg2): self.arg1 = arg1 self.arg2 = arg2
在这个例子中,构造方法__init__
有两个参数arg1和arg2。当创建MyClass的实例时,这些参数将被传递给构造方法,并且使用它们来初始化实例的属性。
例如,可以创建一个名为my_instance的MyClass实例,如下所示:
python my_instance = MyClass("Hello", "World")
在创建my_instance时,Python将调用MyClass的__init__
方法,并将"Hello"和"World"作为参数传递给它。然后,__init__
方法将使用这些参数来初始化my_instance的属性arg1和arg2。
除了在创建实例时初始化属性之外,构造方法还可以用于执行其他操作,例如设置对象的属性或调用其他方法。
8.5 魔术方法
8.6 封装
定义·:它指的是将数据(属性)和操作数据的方法(函数)绑定在一起,以防止外部直接访问对象的内部状态。封装通过隐藏对象的内部细节,仅暴露必要的接口,从而实现了数据的安全性和灵活性。
语法:
-
命名约定:使用下划线
_
来指示私有属性或方法,即_variable
表示私有变量。 -
属性方法(Getters 和 Setters):通过提供公共方法来获取和设置私有属性的值,以控制对属性的访问。
-
属性装饰器:使用装饰器
@property
、@<property_name>.setter
和@<property_name>.deleter
来定义属性的获取、设置和删除方法。例子:
class Wife: def __init__(self,name,age,weight): self.nane = name # self.__age = age#2个下划线意味着本质是障眼法 #实际将变量名改为:_类名__age self.set_age(age) self.__weight = weight def get_age(self): return self.__age def set_age(self,value): if 21 <= value <= value: self.__age = value else: raise ValueError("我不要") w01 = Wife("铁锤公主",27,87) #重新创建了新实例变量(没有改变类中定义的__age)应该改为w01._Wife__age = 107 w01.__age = 107 print(w01.set_age()) #print(w01.nane) #print(w01.age) #print(w01.__dict__) #print(w01.weight) class Person: def __init__(self, name, age): self.name = name # 公共属性 self._age = age # 私有属性,通过下划线表示私有 def get_age(self): # 获取私有属性的公共方法 return self._age def set_age(self, new_age): # 设置私有属性的公共方法 if 0 < new_age < 150: self._age = new_age else: print("年龄范围应在0到150之间") # 创建 Person 对象 person1 = Person("Alice", 30) # 使用公共方法获取和设置私有属性 print(person1.get_age()) # 输出: 30 person1.set_age(40) print(person1.get_age()) # 输出: 40 person1.set_age(200) # 输出: 年龄范围应在0到150之间 print(person1.get_age()) # 输出: 40,因为年龄设定不在有效范围内未修改成功 #银行的取钱 class Person: def __init__(self, name, money): self.__name = name self.__money = money @property def name(self): return self.__name @name.setter def name(self, value): self.__name = value @property def money(self): return self.__money @money.setter def money(self, value): self.__money = value class Bank: def __init__(self, name, money): self.__name = name self.__money = money @property def name(self): return self.__name @name.setter def name(self, value): self.__name = value @property def money(self): return self.__money @money.setter def money(self, value): self.__money = value def draw_money(self, person, value): self.money -= value person.money += value print(person.name, "取了", value, "元钱") xm = Person("小明", 0) zsyh = Bank("招商", 10000) zsyh.draw_money(xm, 1000) print(xm.name, "剩余", xm.money, "元") print(zsyh.name, "剩余", zsyh.money, "元") 1. Person 类 python Copy code class Person: def __init__(self, name, money): self.__name = name # 使用双下划线开头的变量表示私有属性 self.__money = money @property def name(self): return self.__name @name.setter def name(self, value): self.__name = value @property def money(self): return self.__money @money.setter def money(self, value): self.__money = value 这个类定义了一个 Person,拥有 name 和 money 两个属性。这些属性都被设置为私有属性(以双下划线 __ 开头),意味着在类的外部不能直接访问或修改这些属性。而通过 @property 装饰器,为每个私有属性提供了 getter 和 setter 方法,允许在类的外部通过这些方法间接地访问和修改私有属性的值。 2. Bank 类 python Copy code class Bank: def __init__(self, name, money): self.__name = name self.__money = money @property def name(self): return self.__name @name.setter def name(self, value): self.__name = value @property def money(self): return self.__money @money.setter def money(self, value): self.__money = value def draw_money(self, person, value): self.money -= value person.money += value print(person.name, "取了", value, "元钱") 这个类代表一个银行(Bank),也有 name 和 money 两个私有属性。与 Person 类类似,它也有 getter 和 setter 方法来访问和修改这些属性的值。另外,这个类还定义了一个 draw_money 方法,用于模拟取款操作。这个方法减少了银行的余额(self.money -= value),增加了某个人的余额(person.money += value),然后输出取款人的名字和取款金额。 示例代码 python Copy code xm = Person("小明", 0) zsyh = Bank("招商", 10000) zsyh.draw_money(xm, 1000) 在示例代码中,首先创建了一个名为 xm 的 Person 类的实例,名字为 "小明",初始金额为 0。然后创建了一个名为 zsyh 的 Bank 类的实例,表示招商银行,初始金额为 10000。接着调用了 zsyh.draw_money(xm, 1000) 方法,这个方法模拟了小明从招商银行取款1000元的操作。最后输出了小明和招商银行的剩余金额。 这样的封装设计有利于保护数据,只允许在类内部通过公开的接口(即 getter 和 setter 方法)来访问和修改数据,从而确保了数据的安全性和正确性。
8.7 继承
语法:
在 Python 中,可以通过以下语法实现继承:
pythonCopy codeclass ParentClass: # 父类的属性和方法 class ChildClass(ParentClass): # 子类继承父类,并可以添加自己的属性和方法
作用:
代码复用和组织: 继承允许子类使用父类的功能,避免重复编写代码。
-
扩展性: 子类可以增加额外的功能或修改继承的功能,实现更高层次的抽象。
-
多态性: 通过多态性,可以使不同的类对象对相同的消息作出不同的响应,提高代码的灵活性和可维护性。
从编码角度来说 :
-
先有父再有子: 在代码中,首先定义了父类
Person
,然后通过class Student(Person)
和class Teacher(Person)
分别定义了Student
和Teacher
两个子类。这种顺序在编码实现上是符合逻辑的。 -
代码复用性: 子类
Student
和Teacher
继承了父类Person
的say()
方法,这意味着子类不需要重复编写say()
方法,而是可以直接使用父类中已经定义好的方法。
从设计角度来看:
-
先有子再有父: 从设计的角度来看,可以将这种继承关系比喻为一种抽象和具体的关系。先有具体的子类(
Student
和Teacher
),它们继承了更为抽象的父类Person
,这符合面向对象编程中的抽象和泛化概念。 -
类之间的关系: 子类
Student
和Teacher
分别代表了学生和老师这两种具体角色,而这些角色都具备了“说话”的能力,即say()
方法,这种关系也符合现实世界中的某种继承关系。
在这个例子中,继承机制使得子类具备了父类的一些通用特征和行为,同时也可以在子类中添加自己特有的方法和属性,这种设计使得代码更加灵活和可扩展。
单继承与多继承
-
单继承: 一个类只能继承一个父类。Python 中,一个类可以通过单继承获得另一个类的属性和方法。
pythonCopy codeclass Animal: def __init__(self, name): self.name = name def speak(self): pass class Dog(Animal): def speak(self): return "Woof!" dog = Dog("Buddy") print(dog.name) # 输出:Buddy print(dog.speak()) # 输出:Woof!
-
多继承: 一个类可以继承多个父类。Python 支持多继承,一个类可以同时继承多个父类的属性和方法。
pythonCopy codeclass Flyable: def fly(self): return "I can fly!" class Swimmable: def swim(self): return "I can swim!" class Amphibian(Animal, Flyable, Swimmable): pass frog = Amphibian("Freddy") print(frog.name) # 输出:Freddy print(frog.speak()) # 输出:None(因为 Amphibian 没有定义 speak 方法) print(frog.fly()) # 输出:I can fly! print(frog.swim()) # 输出:I can swim!
在多继承中,要注意可能引发的命名冲突和类之间的复杂关系。使用多继承时,确保理解每个父类的作用,以避免潜在的问题。
多继承的的同名方法的解析顺序:类自身----》父类继承列表(由左至右)-------》再上父类
内置可重写函数与运算重载符的用法
""" 内置可重写函数 """ class StudentModel: def __init__(self,name = "",age = 0 ,score = 0, id = 0): self.name = name self.age = age self.score = score self.id = id #对象 --->字符串(随意格式) def __str__(self): return "我叫%s,编号%d,年龄%d,成绩是%d"%(self.name,self.id,self.age,self.score) #对象--> 字符串(解释器有识别)通俗来说有格式的有python def __repr__(self): return"StudentModel('%s',%d,%d,%d)"%(self.name,self.id,self.age,self.score) s01 = StudentModel("无忌",27,100,101) print(s01) #可以将字符串进行运算eval,exec.有一个是对小串进行运算一个是对大串进行运算 re = eval("1+4*5") print(re) str02 = repr(s01) print(str02) #克隆一个对象,将一个数据完全复制出来并且独立 #repr返回python格式的字符串(创建对象) #eval根据字符串执行代码 s02 = eval(repr(s01)) print(s02) s02.name = "老张" print(s01.name) print(s02) #练习;创建Enemy类对象,将对象打印在控制台体)格式自定义) #克隆Enemy类对象体会克隆对象变量的改变不影响原对象的 class Enemy: def __init__(self, name, hp, atk, defense): self.name = name self.hp = hp self.atk = atk self.defense =defense def __str__(self): return"敌人的名字叫做%s,血量%d,攻击力%d,防御力%d"%(self.name,self.hp,self.atk,self.defense) def __repr__(self): return"Enemy('%s',%d,%d,%d)"%(self.name,self.hp,self.atk,self.defense) m01 = Enemy("张三",100,32,32) print(m01) m02 = repr(m01) print(m02) m03 = eval(repr(m01)) print(m03) m03.name = "lisi" print(m03) """ 运算重载符 """ 加法运算符 + 的重载: python Copy code class Point: def __init__(self, x, y): self.x = x self.y = y def __add__(self, other): if isinstance(other, Point): return Point(self.x + other.x, self.y + other.y) return NotImplemented # 使用 p1 = Point(1, 2) p2 = Point(3, 4) result = p1 + p2 print(result.x, result.y) # 输出:4 6
8.8 多态
重写
多态:调用父执行子
#多态:调用父执行子,继承:隔离子类变化,将子类共性提取到父类,约束子类行为 class Vehicle: def transport(self,str_position): pass #客户端代码,用于交通工具 class Person: def __init__(self,name): self.name = name def go_to(self,vehicle,str_position): #多态:调用父执行子 #调用的是交通工具的运输方法 #执行的是飞机的运输方法或者汽车的运输方法 vehicle.transport(str_position) #-----------------------------以上是架构师完成的,以下是程序员完成 class Car(Vehicle): def transport(self,str_position): print("汽车开到",str_position) class Airplane(Vehicle): def transport(self,str_position): print("飞机飞到",str_position) p01 = Person("老张") c01 = Car() a01 = Airplane() p01.go_to(c01,"东北") p01.go_to(a01,"东北")
实例方法 ,类方法,静态方法三者的区别以及用法·
-
实例方法(Instance Method):
-
定义方式: 实例方法在类中定义,第一个参数通常是
self
,表示实例本身。 -
调用方式: 通过实例调用,自动传递实例本身作为第一个参数。
-
作用: 实例方法可以访问并操作实例的属性,也可以调用其他实例方法。
pythonCopy codeclass MyClass: def instance_method(self): print("This is an instance method.") obj = MyClass() obj.instance_method()
-
-
类方法(Class Method):
-
定义方式: 使用
@classmethod
装饰器定义,第一个参数通常是cls
,表示类本身。 -
调用方式: 通过类名或实例调用,自动传递类本身作为第一个参数。
-
作用: 类方法可以访问并操作类级别的属性,通常用于与类相关的操作。
pythonCopy codeclass MyClass: class_variable = "Class Variable" @classmethod def class_method(cls): print(f"This is a class method. Accessing class variable: {cls.class_variable}") MyClass.class_method()
-
-
静态方法(Static Method):
-
定义方式: 使用
@staticmethod
装饰器定义,无需额外的参数表示类或实例。 -
调用方式: 通过类名或实例调用,与类和实例无关。
-
作用: 静态方法通常独立于类和实例的状态,用于执行与类和实例无关的操作。
pythonCopy codeclass MyClass: @staticmethod def static_method(): print("This is a static method.") MyClass.static_method()
-
区别总结:
-
实例方法操作实例属性,通过实例调用,自动传递实例本身作为第一个参数(
self
)。 -
类方法操作类属性,通过类名或实例调用,自动传递类本身作为第一个参数(
cls
)。 -
静态方法与类和实例无关,通过类名或实例调用,不需要额外的参数表示类或实例。
选择使用哪种方法取决于方法内部是否需要访问实例或类的属性。
9. 异常
9.1 异常的捕获
定义:处理程序运行期间的导致中断,停止或者错误,通过使用异常捕获可以使用程序可以运行而不至于中断,能在异常发生时进行适当的处理,而不是直接终止执行。
作用:进行错误处理,程序流程控制,资源管窥等等
-
try: 用于包含可能引发异常的代码块。如果在
try
代码块中发生异常,程序会跳转到与该异常匹配的except
代码块执行。 -
except: 用于捕获异常。在
except
代码块中,你可以指定捕获哪些类型的异常,也可以不指定类型(捕获所有异常)。如果try
代码块中发生异常,Python 会在这里寻找匹配的except
块。 -
else: 用于指定在
try
代码块中没有发生异常时执行的代码。如果try
代码块中没有发生异常,那么将执行else
代码块中的代码。 -
finally: 用于指定无论是否发生异常都将执行的代码。通常用于清理资源或确保某些操作一定会执行。
以下是一个包含 try
, except
, else
, 和 finally
的异常处理示例:
pythonCopy codetry: # 可能引发异常的代码块 num1 = int(input("输入被除数:")) num2 = int(input("输入除数:")) result = num1 / num2 except ValueError: print("输入值错误,请输入整数。") except ZeroDivisionError: print("除数不能为零。") else: # 如果没有异常发生时执行的代码 print(f"结果为:{result}") finally: # 无论是否发生异常都会执行的代码 print("执行 finally 块。")
在这个例子中,用户输入两个数字,程序尝试计算它们的除法。如果输入不是整数,或者除数为零,相应的异常将被捕获并处理。如果没有异常发生,将执行 else
块中的代码。最终,finally
块中的代码将无论如何都会执行。
9.2 异常的传递
迭代
迭代是通过循环访问集合中的元素的过程。迭代器(iterator)是支持迭代的对象,而迭代是通过 for...in
循环实现的。
以下是关于迭代的一些知识点、语法和例子:
-
可迭代对象(Iterable):可迭代对象是指那些可以被迭代(遍历)的对象。常见的可迭代对象包括列表、元组、字符串、字典等。
-
迭代器(Iterator):迭代器是实现了迭代协议的对象,它包含两个方法:
__iter__()
和__next__()
。__iter__()
返回迭代器对象自身,而__next__()
返回下一个元素。 -
for 循环:
for
循环是 Python 中用于迭代的主要语句。它可以遍历可迭代对象中的所有元素。pythonCopy code# 使用 for 循环迭代列表 my_list = [1, 2, 3, 4, 5] for item in my_list: print(item)
-
iter()
和next()
函数:iter()
函数用于获取迭代器,而next()
函数用于获取迭代器的下一个元素。pythonCopy code# 使用 iter() 和 next() 迭代列表 my_list = [1, 2, 3, 4, 5] iter_list = iter(my_list) print(next(iter_list)) # 输出:1 print(next(iter_list)) # 输出:2
-
自定义迭代器:可以通过在类中实现
__iter__()
和__next__()
方法来创建自定义迭代器。pythonCopy code# 自定义迭代器示例 class MyIterator: def __init__(self, start, end): self.current = start self.end = end def __iter__(self): return self def __next__(self): if self.current < self.end: result = self.current self.current += 1 return result else: raise StopIteration my_iter = MyIterator(1, 5) for item in my_iter: print(item)
""" list01 = [3,23,43,21,321] for item in list01: print(item) #原理 #获取迭代器 iterator = list01.__iter__() #循环获取下一个元素 while True: try: item = iterator.__next__() print(item) #遇到异常停止迭代 except StopIteration: break#退出循环 """ #迭代器 class Skill: pass class SkillIterator: def __init__(self,target): self._target = target self._index = -1 def __next__(self): #如果没有数据,则抛出异常 if self._index > len(self._target)-1: return StopIteration #返回下一个数据 self._index += 1 return self._target[self._index] class SkillManager: def __init__(self): self._skills = [] def add_skill(self,skill): self._skills.append(skill) def __iter__(self): #创建迭代器对象,并传递需要迭代的对 return SkillIterator(self._skills) manager = SkillManager() manager.add_skill(Skill()) manager.add_skill(Skill()) manager.add_skill(Skill()) manager.add_skill(Skill()) #for item in range: # print(item) iterator = manager.__iter__() while True: try: item = iterator.__next__ print(item) except: break
生成器
-
__iter__
方法是一个特殊方法,用于返回一个迭代器对象。迭代器对象必须实现__iter__
方法和__next__
方法。 -
yield
语句用于产生值,并暂停生成器的执行,保存其状态。在这里,__iter__
方法使用yield
来逐个产生self._skills
中的元素。 -
self._skills
应该是一个可迭代对象,比如一个列表或集合。
下面是一个简单的例子,演示如何使用这个类的实例进行迭代:
pythonCopy codeclass MyClass: def __init__(self, skills): self._skills = skills def __iter__(self): for item in self._skills: yield item # 创建一个 MyClass 实例 my_instance = MyClass(['Python', 'Java', 'C++']) # 使用迭代器遍历实例 for skill in my_instance: print(skill)
在这个例子中,__iter__
方法通过 yield
逐个产生 self._skills
中的技能,并且通过 for
循环在每次迭代中调用。
lambda的用法
lambda
是 Python 中用于创建匿名函数的关键字。这种函数是一种简单的、临时的函数,通常只包含单一的表达式。
语法格式:
pythonCopy code lambda arguments: expression
-
lambda
:关键字。 -
arguments
:函数参数。 -
expression
:函数体,即一个表达式。
lambda
函数的主要作用是创建一个小型的、临时使用的函数,通常用于一些简单的操作。它的定义形式比较紧凑,适合于一些不需要命名的场景。
例子:
pythonCopy code# 使用 lambda 创建一个简单的加法函数 add = lambda x, y: x + y print(add(3, 5)) # 输出 8 # 使用 lambda 进行平方运算 square = lambda x: x**2 print(square(4)) # 输出 16 # lambda 函数可以作为参数传递给其他函数 numbers = [1, 2, 3, 4, 5] squared_numbers = list(map(lambda x: x**2, numbers)) print(squared_numbers) # 输出 [1, 4, 9, 16, 25]
10. 正则
10.1 基础匹配
10.2 元字符匹配
闭包
定义:指在一个函数内部定义的函数,并且内部函数可以访问外部函数的局部变量,即使外部函数已经执行结束。闭包可以在函数内部创建一个局部作用域,同时又能访问外部函数的局部变量,使得这些变量的生命周期得到延长,不会随着外部函数的执行结束而被销毁
语法:
语法定义: def 外部函数名(参数): 外部变量 def 内部函数(参数): 使用外部变量 return 内部函数
作用:
"""" 闭包 函数作为返回值 """ #三大要素 #必须有一个内嵌函数 #内嵌函数必须引用外部函数中变量 #外部函数返回值必须是内嵌函数 """ 调用: 变量 = 外部函数名(参数) 变量(函数) """ def fun01(): a = 1 def fun02(): print(a) return fun02 #调用外部函数,返回值是内嵌函数 result = fun01() #调用内嵌函数 result()#可以访问外部变量 #闭包作用:指的是fun01执行完毕之后栈帧没有立即释放,而是等着fun02执行 """ 本质:闭包是将内部函数和外部函数执行环境绑定在一起 闭包指的是2个函数执行的环境整合 """ #闭包的应用:逻辑连续,当内部函数被调用时,不脱离当前逻辑 #压岁钱 def give_money(money): """ 得到的压岁钱 :param money: :return: """ print("得到的压岁钱%d"%money) def buy_child(target,price): """ :param target:购买的东西 :param price: 花费的金额 :return: """ nonlocal money#声明外部变量 if money >= price: money -= price print("购买的商品%s,购买花费的压岁钱%d"%(target,price)) else: print("钱不够了") return buy_child #下列代码是一个连续的逻辑 re = give_money(10000) re("蝴蝶刀",9876) re("可燃冰",987) class RedEnvelope: def __init__(self, money): self.money = money def give_money(self): print("得到的压岁钱:%d" % self.money) def buy_child(self, target, price): if self.money >= price: self.money -= price print("购买的商品:%s,花费的压岁钱:%d" % (target, price)) else: print("钱不够了") # 示例用法 if __name__ == "__main__": red_envelope = RedEnvelope(10000) # 创建一个压岁钱账户,初始余额为10000元 red_envelope.give_money() # 打印得到的压岁钱 red_envelope.buy_child("蝴蝶刀", 9876) # 购买蝴蝶刀 red_envelope.buy_child("可燃冰", 987) # 购买可燃冰
装饰器
装饰器是 Python 中一种特殊的语法,它可以用来修改或增强函数或类的功能,而不需要修改它们的源代码。装饰器本质上是一个函数,它接受一个函数或类作为参数,并返回一个新的函数或类。在函数或类定义之前使用 @装饰器函数名
的语法,就可以将该函数或类传递给装饰器函数进行修饰。
装饰器的语法结构如下:
pythonCopy code@decorator def function(): pass
或者:
pythonCopy code@decorator_with_args(arg) def function(): pass
"""" 装饰器 """ #已有功能 def enter_background(): verify_permissions() print("切入后台") print("权限验证") def delete_order(): verify_permissions() print("删除订单") print("权限验证") enter_background() delete_order() #需求:对以下的两个功能增加权限验证 #需要增加的功能 def verify_permissions(): print("权限验证") #已有功能 def enter_background(): verify_permissions() print("切入后台") def delete_order(): verify_permissions() print("删除订单") enter_background() delete_order() def verify_background(func): def wrapper(): print("权限验证") func() return wrapper def enter_background(): print("切入后台") def delete_order(): print("删除订单") enter_background = verify_background(enter_background) delete_order = verify_background(delete_order) enter_background() delete_order() def verify_background(func): def wrapper(): print("权限验证") func() return wrapper @verify_background def enter_background(): print("切入后台") @verify_background def delete_order(): print("删除订单") enter_background() delete_order() #缺点如果已有功能参数不统一,则无法包装 def verify_background(func): def wrapper(*args,**kwargs): #*arges表示形参的位置无限,**kwargs表示形参的关键字无限 print("权限验证") func(*args,**kwargs) return wrapper #enter_background = verify_background(enter_background) 新功能 = 新功能 + 旧功能 @verify_background def enter_background(long_id,pwd): print(long_id,pwd,"切入后台") @verify_background def delete_order(id): print(id,"删除订单") #delete_order = verify_background(delete_order) enter_background("ABC",123456) delete_order(83972) """ 定义:在不改变原函数的调用以及内部代码情况下,为其增加新功能 语法:def 函数装饰器名称(func) def (wrapper)内嵌函数(*args,**kwargs): 需要添加的新功能 return func(*args,**kwargs) return wrapper @函数装饰器名称 def 原函数名称(参数): 函数体 本质:原函数名称 = 函数装饰器(原函数名称) 装饰链:一个函数可以被多个装饰器修饰,执行顺序是从近到远 """ """ 在不改变原有功能的(存取钱)的定义和调用情况下 增加验证账号的功能 """ def deposit(money): print("存%d钱喽" % money) def yan_zheng(func): def wrapper(*arges,**kwargs): print("验证账户") return func(*arges,**kwargs) return wrapper @yan_zheng def deposit(money): print("存钱%d"%money) @yan_zheng def withdraw(login_id,pwd): print("取钱楼",login_id,pwd) deposit(1000) withdraw(2134,3123) import time """ time模块在Python中提供了各种与时间相关的功能。以下是一些常用的time模块的方法和功能: time.time():返回当前时间的时间戳(从1970年1月1日00:00:00 UTC开始的秒数)。 time.sleep(seconds):使程序暂停指定的秒数。 time.localtime():返回当前时间的本地时间表示,返回一个time.struct_time对象。 time.gmtime():返回当前时间的UTC时间表示,同样返回一个time.struct_time对象。请注意,这个时间比中国本地时间(东八区)早8个小时。 time.ctime(seconds):将一个时间戳转换为本地时间的字符串表示。如果不提供时间戳,则默认为当前时间。 time.asctime(t):将一个time.struct_time对象转换为字符串表示。 time.mktime(t):将一个time.struct_time对象转换为一个时间戳。 time.strftime(format, t):将时间格式化为字符串。如果t未指定,则默认为当前时间。format可以包含各种时间相关的指令,如%Y代表四位数的年份,%m代表月份,%d代表日,%H代表小时,%M代表分钟,%S代表秒等。 下面是一些使用示例: python import time # 获取当前时间戳 timestamp = time.time() print("当前时间戳:", timestamp) # 暂停5秒 time.sleep(5) # 获取当前本地时间 local_time = time.localtime() print("当前本地时间:", time.asctime(local_time)) # 获取当前UTC时间 utc_time = time.gmtime() print("当前UTC时间:", time.asctime(utc_time)) # 将时间戳转换为字符串 time_str = time.ctime(timestamp) print("时间戳对应的本地时间:", time_str) # 格式化时间 formatted_time = time.strftime("%Y-%m-%d %H:%M:%S") print("格式化后的时间:", formatted_time) 请注意,time模块提供的功能主要是与时间戳和结构化时间之间的转换,以及时间的格式化和输出有关。如果你需要更复杂的日期和时间处理功能,可能需要考虑使用datetime模块。 """ def print_excute_time(func): def wrapper(*arges,**kwargs): #记录调用前的时间(( start_time = time.time() result = func(*arges,**kwargs) #记录调用后的时间 execute_time = time.time() - start_time print("执行时间是:",execute_time) return result return wrapper @print_excute_time def fun01(): time.sleep(2) print("fun01执行完毕") @print_excute_time def fun02(a): time.sleep(1) print("fun02执行完成了,参数是",a) fun01() fun02(100)