字面量

在代码中,被写下来的的固定的值,称之为字面量

类型 描述 说明
数字(Number) 整数(int)
浮点数(float)
复数(complex)
布尔(bool)
整数(int),如:10、-10
浮点数(float),如:13.14、-13.14
复数(complex),如:4+3j,以j结尾表示复数
布尔(bool)表达现实生活中的逻辑,即真和假,True表示真,False表示假。True本质上是一个数字记作1,False记作0
字符串(String) 描述文本的一种数据类型 字符串(string)由任意数量的字符组成,字符串需要用双引号包围起来。
列表(List) 有序的可变序列 Python中使用最频繁的数据类型,可有序记录一堆数据
元组(Tuple) 有序的不可变序列 可有序记录一堆不可变的Python数据集合
集合(Set) 无序不重复集合 可无序记录一堆不重复的Python数据集合
字典(Dictionary) 无序Key-Value集合 可无序记录一堆Key-Value型的Python数据集合

基于print语句完成各类字面量的输出。

1
2
3
4
5
6
# 写一个整数字面量
11110000
# print(字面量),如:
print(10) # 输出整数10
print(13.14) # 输出浮点数13.14
print("人生苦短,我用Python") # 输出字符串:人生苦短,我用Python

注释

在程序代码中对程序代码进行解释说明的文字。
作用:注释不是程序,不能被执行,只是对程序代码进行解释说明,让别人可以看懂程序代码的作用,能够大大增强程序的可读性。
注释的分类:

  • 单行注释:以#开头,#右边的所有文字当作说明。
1
2
# 我是单行注释
print(10) # 输出整数字面量
  • 多行注释: 以 一对三个双引号"""注释内容"""引起来。
1
2
3
4
5
"""
我是多行注释
"""
109
print(10)

变量

在程序运行时,能储存计算结果或能表示值的抽象概念,存储的目的是为了重复使用。
变量存储的数据,是可以发生改变的。
Python 可以同一行显示多条语句,方法是用分号 ;分开。
Python 中的变量赋值不需要类型声明。
每个变量在内存中创建,都包括变量的标识,名称和数据这些信息。
每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。
等号=运算符左边是一个变量名,等号=运算符右边是存储在变量中的值。
变量的定义格式:变量名称 = 变量的值

1
2
3
4
5
6
7
8
9
counter = 100 # 赋值整型变量
miles = 1000.0 # 浮点型
name = "John" # 字符串
a = b = c = 1 # 创建一个整型对象,值为1,三个变量被分配到相同的内存空间上。
d, e, f = 1, 2, "john" # 两个整型对象 1 和 2 分别分配给变量 d 和 e,字符串对象 "john" 分配给变量 f。
print("整数变量",counter,"整数变量变换",counter-15) # print语句输出多份内容,使用‘,’分隔。
print(miles)
print(name)
print(f)

数据类型

通过type()语句可得到数据的类型。

语法:type(被查看类型的数据)

1
2
3
4
5
6
7
8
9
10
11
# 在print语句中,直接输出类型信息
print(type("这是字符串")) # <class 'str'>

# 用变量存储type()的结果(返回值)
string_type = type("这是字符串")
print(string_type) # <class 'str'>

# 通过type(变量),查看变量中存储的数据的类型
name = "这是字符串"
string_type = type(name)
print(string_type) # <class 'str'>

字符串类型

字符串有3种不同的定义方式,每种引号的开始与结束必须是相同类型的。

  • 单引号定义法。
  • 双引号定义法。
  • 三引号定义法。
    • 使用变量接收它,它就是字符串,不使用变量接收它,就可以作为多行注释使用。
    • 三引号允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符。

引号的嵌套:

  • 可以使用转义字符\来进行转义。
  • 单引号内可以写双引号或双引号内可以写单引号。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 双引号定义法
text1 = "字符串"

# 单引号定义法
text2 = '字符串'

# 三引号定义法,可定义在一行或多行中,打印多行时会换行输出
text3 = """
字符串
字符串
字符串
"""
# 字符串之间的嵌套使用
"'字符串'"
'"字符串"'

# 转义字符\来进行转义输出
'\'字符串'

字符串拼接

如果有两个字符串(文本)字面量,可以将其拼接成一个字符串,通过+号即可完成,如“hello+“world”

一般,字面量和变量或变量和变量之间会使用拼接,但字符串无法和非字符串变量进行拼接,因为类型不一致,无法接上。如:

1
2
3
4
5
6
7
8
9
10
# 字符串拼接字符串变量
name = "张三"
hobby = "写Python"
print("我叫:"+name+",我会"+hobby+"!")

# 字符串拼接非字符串变量
name = "张三"
time = 8
print("我叫:"+name+",现在"+time+"点") # TypeError: can only concatenate str (not "int") to str

字符串格式化

字符串格式化-字符串格式符

Python 支持格式化字符串的输出 。最基本的用法是将一个值插入到一个有字符串格式符 %s的字符串中。
在 Python 中,字符串格式化使用与Csprintf函数一样的语法。
常见的字符串格式化符号有%s格式化字符串%d格式化整数%f格式化浮点数字,可指定小数点后的精度等。
Python 2.6开始,新增了一种格式化字符串的函数str.format(),它增强了字符串格式化的功能。

1
2
3
4
5
6
7
# %表示占位符
# s表示将变量变成字符串放入占位的地方,数字也可用%s占位,会将数字转换成了字符串
# .2f代表指定保留两位小数
name = 'John'
height = 1.8
message = "My name is %s and weight is %s kg and height is %.2f m!" % (name,60,height)
print(message) # My name is John and weight is 60 kg and height is 1.80 m!

数字精度控制:
可使用辅助符号"m.n"来控制数据的宽度和精度。

  • m,控制宽度,要求是数字(很少使用),设置的宽度小于数字自身,不生效。
  • .n,控制小数点精度,要求是数字,会进行小数的四舍五入。
  • %5d:表示将整数的宽度控制在5位,如数字11被设置后,就会变成:[空格][空格][空格]11,用三个空格补足宽度。
  • %7.2f:表示将宽度控制为7,将小数点精度设置为2, 小数点和小数部分也算入宽度计算。如数字11.345被设置后,结果是:[空格][空格]11.35。2个空格补足宽度,小数部分限制2位精度后,四舍五入为 .35。
  • %.2f:表示不限制宽度,只设置小数点精度为2,如11.345被设置后,,结果是11.35。

字符串格式化-f字符串

f-字符串格式,也称为“格式化字符串文字”。f-string是格式化字符串的一种很好且简单的方法,适用于Python V 3.6+。

通过语法:f"内容{变量}"的格式来快速格式化。
这种写法不做精度控制,原样输出,也不理会类型,适用于快速格式化字符串。

1
2
3
4
5
name = 'John'
weight = 60
height = 1.8
message = f"My name is {name} and weight is {weight} kg and height is {height} m!"
print(message)

字符串格式化-格式化表达式

表达式就是一个具有明确结果的代码语句,如1 + 1type(“字符串”)3 * 5等。
在变量定义的时候,如age = 11 + 11,等号右侧的就是表达式,也就是有具体的结果,将结果赋值给了等号左侧的变量。
在无需使用变量进行数据存储的时候,可以直接格式化表达式。
通过语法:f"{表达式}""%s\%d\%f" %(表达式、表达式、表达式)来格式化表达式。

1
2
3
print("1+1=%d" %(1+1)) # 1+1=2
print(f"2+2={2+2}") # 2+2=4
print("整数在Python中的类型:%s" %type(1)) # 整数在Python中的类型:<class 'int'>

数据类型转换

常见的转换语句:

语句(函数) 说明
int(x) 将x转换为一个整数
float(x) 将x转换为一个浮点数
str(x) 将对象 x 转换为字符串

这三个语句,都是带有结果的(返回值),可用print直接输出,或用变量存储结果值。

类型转换不是万能的,需要注意:

  1. 任何类型,都可以通过str(),转换成字符串。
  2. 字符串内必须真的是数字,才可以将字符串转换为数字。
  3. 浮点数转整数会丢失精度,也就是小数部分。
1
2
v_str = "这个不是数字"
num = int(v_str) # ValueError: invalid literal for int() with base 10: '这个不是数字'

标识符

标识符:是用户在编程的时候所使用的一系列名字,用于给变量、类、方法等命名。
Python中,标识符命名的规则主要有3类:

  • 内容限定
    • 标识符命名中,只允许出现:英文、中文、数字、下划线(_)这四类元素。其余任何内容都不被允许。
    • 以单下划线开头_foo的代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用from xxx import * 而导入。
    • 以双下划线开头的__foo代表类的私有成员,以双下划线开头和结尾的__foo__代表 Python 里特殊方法专用的标识,如__init__()代表类的构造函数。
    • 不推荐使用中文,数字不可以开头
  • 大小写敏感
    • 字母的大写和小写,是完全能够区分的。
  • 不可使用关键字
    • 所有Python的关键字除内置常量False、None、True外只包含小写字母。
    • 可通过下面语句获取在Python中的关键字。这些关键字不能用作常数或变数,或任何其他标识符名称。
1
2
3
4
5
import keyword
# ['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
print(keyword.kwlist)
# 35
print(len(keyword.kwlist))

标识符的命名规范

  • 变量的命名规范:
    • 见名知意、多个单词组合变量名,要使用下划线做分隔、英文字母全小写。
  • 类的命名规范:
  • 方法的命名规范:

运算符

算术运算符

以下假设变量: a=10,b=20:

运算符 描述 实例
+ 两个对象相加 a + b 输出结果 30
- 得到负数或是一个数减去另一个数 a - b 输出结果 -10
* 两个数相乘或是返回一个被重复若干次的字符串 a * b 输出结果 200
/ b / a 输出结果 2 ,9/2 输出结果 4.5
// 取整除 返回商的整数部分
9//2 输出结果 4 , 9.0//2.0 输出结果 4.0 ,-9//2 输出结果 -5
% 取余 返回除法的余数 b % a 输出结果 0
** 指数 a**b 为10的20次方, 输出结果 100000000000000000000

比较(关系)运算符

以下假设变量: a=10,b=20:

运算符 描述 实例
== 等于 a == b 返回False。
!= 不等于 a != b 返回True。
<> 不等于
python 3 已废弃。
a <> b 返回 True。
> 大于 a > b 返回 False。
< 小于 a < b 返回 True。
>= 大于等于 a >= b 返回 False。
<= 小于等于 a <= b 返回 True。

赋值运算符

以下假设变量: a=10,b=20:

运算符 描述 实例
= 简单的赋值运算符 c = a + ba + b 的运算结果赋值为 c
+= 加法赋值运算符 c += a 等效于 c = c + a
-= 减法赋值运算符 c -= a 等效于 c = c - a
*= 乘法赋值运算符 c *= a 等效于 c = c * a
/= 除法赋值运算符 c /= a 等效于 c = c / a
%= 取模赋值运算符 c %= a 等效于 c = c % a
**= 幂赋值运算符 c **= a 等效于 c = c ** a
//= 取整除赋值运算符 c //= a 等效于 c = c // a

逻辑运算符

位运算符

成员运算符

身份运算符

运算符优先级


数据输入

Python 3中 input() 函数接受一个标准输入数据,返回为 string 类型,input语句,用来获取键盘输入。

Python 2中input()相等于eval(raw_input(prompt)),用来获取控制台的输入,因为引入了eval(),所以会存在代码注入的风险。
Python 2中raw_input()将所有输入作为字符串看待,返回字符串类型。而input()在对待纯数字输入时具有自己的特性,它返回所输入的数字的类型( int, float )。

Python 3 中,将 Python 2 的raw_input()函数保留,重命名为input(),同时移除了 Python 2的input()函数。因此,在 Python 3 中,是不存在input()函数代码注入风险的。

通过语法:input([prompt]),用以在使用者输入内容之前显示提示信息prompt。

注意,无论键盘输入什么类型的数据,获取到的数据永远都是字符串类型。

1
2
3
4
5
6
print("输入姓名")
name = input()
print("欢迎访问,%s" % name)
# 简化 input()语句其实是可以在要求使用者输入内容前,输出提示内容
name = input("输入姓名")
print("欢迎访问,%s" % name)

判断语句

Python判断语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块。

布尔类型的字面量

在Python中,可以表示真假的数据类型是布尔类型

  • 字面量True表示真。
  • 字面量False表示假。
  • Python程序语言指定任何非0和非空(null)值True0 或者 nullFalse

除了可以定义布尔类型外,还可以通过比较(关系)运算符计算得到布尔类型的结果。

1
2
3
4
boolean = True
result = (1==1)
print(boolean == result) # True
print(type(boolean)) # <class 'bool'>

if语句

Python 编程中if语句用于控制程序的执行,基本形式为:

1
2
if 判断条件:
执行语句……

其中”判断条件”成立时(非零),则执行后面的语句,而执行内容可以多行,以缩进来区分表示同一范围。

if语句的注意点:

  • 判断条件的结果一定要是布尔类型。
  • 不要忘记判断条件后的:引号。
  • 归属于if语句的代码块,需在前方填充4个空格缩进,不要用Tab补全,Python通过缩进判断代码块的归属关系。

if else语句

1
2
3
4
if 判断条件:
执行语句……
else
执行语句……

if和其代码块,条件满足时执行,else搭配if的判断条件,当不满足的时候执行。

if else语句的注意点:

  • else不需要判断条件,当if的条件不满足时,else执行。
  • 和if的代码块一样,else的代码块同样需要4个空格作为缩进。

if elif else语句

当判断条件为多个值时,可以使用以下形式:

1
2
3
4
5
6
7
8
if 判断条件1:
执行语句1……
elif 判断条件2:
执行语句2……
elif 判断条件3:
执行语句3……
else:
执行语句4……

判断是互斥且有顺序的。

  • 满足1,将不会理会2和3和4。
  • 满足2,将不会理会3和4。
  • 1、2、3均不满足,进入else。
  • else也可省略不写,效果等同3个独立的if判断。

由于 python 并不支持switch语句,所以多个条件判断,只能用elif来实现,如果判断需要多个条件需同时判断时,可以使用or(或),表示两个条件有一个成立时判断条件成功;使用and(与)时,表示只有两个条件同时成立的情况下,判断条件才成功。

可以在条件判断中,直接写input语句,节省代码量。

1
2
3
4
5
6
7
print("欢迎访问本系统")
if int(input("输入年龄:")) >= 18:
print("年龄符合,可以访问")
elif input("输入密码:") =="admin":
print("密码正确,admin登录成功")
else:
print("条件不符合")

简单的语句组

可在同一行的位置上使用if条件判断语句,如下实例:

1
2
3
var = 100
if ( var == 100 ) : print("变量 var 的值为100");print("变量 var 的值为200")
print("Good bye!")

判断条件为True时,输出同一行的语句,并且输出最后一条Good bye!语句。
判断条件为False时,仅输出最后一条Good bye!语句。

1
2
3
4
5
6
7
a = [1,2,3]
b = a if len(a) != 0 else ""
print(b)

c=[]
d = c if len(c) != 0 else "c 是一个空列表"
print(d)

判断语句的嵌套

嵌套的关键点,在于:空格缩进。
通过空格缩进,来决定语句之间的:层次关系。

1
2
3
4
5
6
7
8
9
10
print("欢迎参观博物馆")
if int(input("输入年龄:")) > 15 :
print("年龄不符合,不可以免费参观")
print("如果你有邀请码,可免费参观")
if int(input("输入邀请码:")) == 100 :
print("邀请码正确,可免费参观")
else :
print("邀请码错误,掏钱买吧")
else :
print("年龄符合,可以免费参观")

当前判断有2层,当外层if满足条件时,才会执行内层if判断;当外层if不满足,直接执行外层esle。


循环语句

Python循环语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务。

while循环

Python 编程中 while 语句用于循环执行程序。

while循环基本形式

1
2
while 判断条件(condition):
执行语句(statements)……

判断条件可以是任何表达式,任何非零、或非空(null)的值均为true。
执行语句可以是单个语句或语句块。
当判断条件假 false 时,循环结束。

while循环注意点:

  1. while的条件需得到布尔类型,True表示继续循环,False表示结束循环。
  2. 需要设置循环终止的条件,如i += 1配合 i < 100,就能确保100次后停止,否则将无限循环。
  3. 空格缩进和if判断一样,都需要设置。

循环使用 else 语句

在 python 中,while … else 在循环条件为 false 时执行 else 语句块:

1
2
3
4
5
6
count = 0
while count < 5:
print(count, " is less than 5")
count = count + 1
else:
print(count, " is not less than 5")

简单语句组

类似 if 语句的语法,如果 while 循环体中只有一条语句,可将该语句与while写在同一行中, 如下所示:

1
2
3
flag = 1
while (flag): print('Given flag is really true!') # 条件判断语句永远为 true,循环将会无限的执行下去,可使用 CTRL+C 来中断循环
print "Good bye!"

while循环嵌套

同判断语句的嵌套一样,循环语句的嵌套,要注意空格缩进,基于空格缩进来决定层次关系。
注意条件的控制,避免出现无限循环(除非真的需要无限循环)。
九九乘法表的案例如下:

1
2
3
4
5
6
7
8
9
10
11
12
# 定义外层循环变量,控制行
i = 1
while i < 10:
# 定义内层循环变量,控制列
j = 1
while j <= i:
# print语句中,加上 end=''即可输出不换行
# 制表符\t,效果等同于在键盘上tab键,可让多行字符串进行对齐
print(j, '*', i, '=', i * j, end='\t')
j += 1
print()
i += 1

for循环

for循环的基础语法

Python中for循环可以遍历任何序列的项目,如一个列表或者一个字符串,for循环也被称之为:遍历循环。

1
2
3
# 从待处理数据集中逐个取出数据,赋值给临时变量
for 临时变量 in 待处理数据集:
循环满足条件时执行的代码

for循环注意点:

  • 同while循环不同,无法定义循环条件,只能从被处理的数据集中,依次取出内容进行处理。

  • 要注意,循环内的语句,需要有空格缩进。

循环使用 else 语句

在 python 中,for … else 表示,for 中的语句和普通的没有区别,else 中的语句会在循环正常执行完(即 for 不是通过 break 跳出而中断的)的情况下执行。

1
2
3
4
5
6
7
8
for num in range(10,20):  # 迭代 10 到 20 之间的数字
for i in range(2,num): # 根据因子迭代
if num%i == 0: # 确定第一个因子
j=num/i # 计算第二个因子
print ('%d 等于 %d * %d' % (num,i,j))
break # 跳出当前循环
else: # 循环的 else 部分
print ('%d 是一个质数' % num)

通过序列索引迭代

另外一种执行循环的遍历方式是通过索引,如下实例:

1
2
for 临时变量 in 待处理数据集(可迭代对象): 
循环满足条件时执行的代码

语法中的待处理数据集,严格来说称之为:可迭代类型
可迭代类型是指,其内容可以一个个依次取出的一种类型,包括:字符串、列表、元组。
通过range语句,获得一个简单的数字序列(可迭代类型的一种)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 获取一个从0开始,到num结束的数字序列(不含num本身)
# 如range(5)取得的数据是:[0, 1, 2, 3, 4]
range(num)
# 获得一个从num1开始,到num2结束的数字序列(不含num2本身)
# 如range(5, 10)取得的数据是:[5, 6, 7, 8, 9]
range(num1,num2)
# 获得一个从num1开始,到num2结束的数字序列(不含num2本身)
# 数字之间的步长,以step为准(step默认为1)
# 如range(5, 10, 2)取得的数据是:[5, 7, 9]
range(num1, num2, step)

# for循环处理数字序列
for i in range(5):
print(i,end='') # 01234 临时变量i的类型<class 'int'>

for循环的变量作用域

for循环的语法中,从数据集(序列)取出的数据赋值给:临时变量。
临时变量,在编程规范上,作用范围(作用域),只限定在for循环内部。
如果在for循环外部访问临时变量,实际上是可以访问到的。在编程规范上,是不允许、不建议这么做的。
如果实在需要在循环外访问循环内的临时变量,可以在循环外预先定义变量i,每一次循环的时候,都会将取出的值赋予变量i,代码如下:

1
2
3
4
i = 0;
for i in range(1, 10):
i = i
print(i) # 9

for循环的嵌套

同while一样,for循环也支持嵌套使用,和while循环一样,需要注意缩进,通过缩进,确定层次关系。
for循环和while循环可以相互嵌套使用。
九九乘法表的案例如下:

1
2
3
4
5
6
7
# 2层循环,外层控制行,内层控制列,
# 使用range语句来得到数字序列进行for循环
# 内层for循环的range最大范围,取决于当前外层循环的数字
for i in range(1, 10):
for j in range(1, i + 1):
print(f"{j} * {i} = {i * j}\t", end='')
print()

while循环和for循环的对比

  • 在循环控制上:
    • while循环可以自定循环条件,并自行控制
    • for循环不可以自定循环条件,只可以一个个从容器内取出数据
  • 在无限循环上:
    • while循环可以通过条件控制做到无限循环
    • for循环理论上不可以,因为被遍历的容器容量不是无限的
  • 在使用场景上:
    • while循环适用于任何想要循环的场景
    • for循环适用于,遍历数据容器的场景或简单的固定次数循环场景

循环中断

break

break语句用来终止循环语句,即循环条件没有False条件或者序列还没被完全递归完,也会停止执行循环语句。

break语句用在while和for循环中。

如果您使用嵌套循环,break语句将停止执行最深层的循环,并开始执行下一行代码。

continue

continue语句用来告诉Python跳过当前循环的剩余语句,然后继续进行下一轮循环。

continue语句用在while和for循环中。

演示

某公司,账户余额有1000元,给20名员工发奖金。
员工编号从1到20,从编号1开始,依次领取奖金,每人可领取100元。
领奖金时,财务判断员工的绩效分(1-10)(随机生成),如果低于5,不发奖金,换下一位。
如果奖金发完了,结束发奖金。
continue用于跳过员工,break直接结束发工资。

1
2
3
4
5
6
7
8
9
10
11
12
13
money = 1000
for i in range(1,21):
import random
score = random.randint(1,10)
if score < 5 :
print(f"员工{i}的绩效分是{score},低于5,不发奖金,下一位。")
continue
else:
money -= 100
print(f"向员工{i}发奖金,账户剩余{money}元")
if money == 0:
print("钱发完了,下次吧")
break

函数

函数:是组织好的,可重复使用的,用来实现特定功能的代码段。
使用过的:input()、print()、str()、int()等都是Python的内置函数。
在Python中,如果将函数定义为class(类)的成员,那么函数会称之为方法

使用函数的好处是:

  • 将功能封装在函数内,可供随时随地重复利用。
  • 提高代码的复用性,减少重复代码,提高开发效率。

函数的定义和使用

可定义一个有想要功能的函数,以下是简单的规则:

  • 函数代码块以def关键词开头,后接函数标识符名称和圆括号()。
  • 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
  • 函数内容以冒号起始,并且缩进。
  • return [表达式]结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None
1
2
3
4
5
6
7
8
# 定义一个函数
def functionname( parameters ):
"函数_文档字符串"
function_suite
return [expression]

# 调用一个函数
functionname(parameters)

定义函数的注意事项:

  • 参数如不需要,可以省略。
  • 返回值如不需要,可以省略。
  • 函数必须先定义后使用。

函数使用步骤:

  • 先定义函数。
  • 后调用函数。
  • 函数可直接使用,不需像方法一样要对象调用。

函数的参数

传入参数的功能是:在函数进行计算的时候,接受外部(调用时)提供的数据。

  • 函数定义中的参数,称之为形式参数。
  • 函数调用中的参数,称之为实际参数。
  • 函数的参数数量不限,使用逗号分隔开。
  • 传入参数的时候,要和形式参数一一对应,逗号隔开。

函数参数种类

使用方式上的不同, 函数有4种常见参数使用方式。

位置参数

调用函数时根据函数定义的参数位置来传递参数,传递的参数和定义的参数的顺序及个数必须一致

1
2
3
4
def functional(name, age):
print(f"姓名:{name}的年龄是{age}") # 姓名:张三的年龄是14

functional("张三", 14)

关键字参数

函数调用时通过“键=值”形式传递参数,可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求。
函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序。

1
2
3
4
5
6
7
8
9
10
11
def functional(name, age, gender):
print(f"姓名:{name}的年龄是{age},性别为{gender}")

# 关键字传参
functional(name="张三", age=14, gender="男")
# 关键字传参,不按照固定位置传参
functional( age=14, name="张三", gender="男")
#关键字传参,与位置参数混用,位置参数必须在前,且匹配参数顺序
functional("张三", age=14, gender="男")
functional("张三", gender="男", age=14)
# functional("张三", "男", age=14) # TypeError: functional() got multiple values for argument 'age'

缺省参数

缺省参数也叫默认参数,用于定义函数,为参数提供默认值。
当调用函数时没有传递参数,就会使用默认是用缺省参数对应的值,当调用函数时缺省参数传值,则修改默认参数值。
所有位置参数必须出现在默认参数前,包括函数定义和调用).

1
2
3
4
5
def functional(name, age, gender = '男'):
print(f"姓名:{name}的年龄是{age},性别为{gender}")

functional("张三", 14) # 姓名:张三的年龄是14,性别为男
functional("张三", 14, "女") # 姓名:张三的年龄是14,性别为女

不定长参数

不定长参数也叫可变参数,用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。

不定长参数的类型:

  1. 位置传递
    位置不定长传递以*号标记一个形式参数,以元组的形式接受参数,形式参数一般命名为args
  2. 关键字传递
    关键字不定长传递以**号标记一个形式参数,以字典的形式接受参数,形式参数一般命名为kwargs
1
2
3
4
5
6
7
8
9
10
11
12
13
# 不定长参数--位置传递
def functional1(*args):
print(args)

functional1("张三", 14) # ('张三', 14)
functional1("张三", 14, "女") # ('张三', 14, '女')

#不定长参数--关键字传递
def functional2(**kwargs):
print(kwargs)

functional2(name="张三", age=14, gender="女") # {'name': '张三', 'age': 14, 'gender': '女'}
functional2(age=14, name="张三", gender="男") # {'age': 14, 'name': '张三', 'gender': '男'}

函数的返回值

函数在执行完成后,使用关键字return来返回给调用者的结果。

函数体在遇到return后就结束了,所以写在return后的代码不会执行。

如果函数没有使用return语句返回数据,那么函数返回了None这个字面量,其类型是:<class 'NoneType'>

函数返回的None,就表示这个函数没有返回什么有意义的内容,也就是返回了空的意思。

None可以主动使用return返回return None,效果等同于不写return语句。

None作为一个特殊的字面量,用于表示:空、无意义,其有非常多的应用场景。

  • 用在函数无返回值上
  • 用在if判断上
    • 在if判断中,None等同于False
    • 一般用于在函数中主动返回None,配合if判断做相关处理
  • 用于声明无内容的变量上
    • 定义变量,但暂时不需要变量有具体值,可以用None来代替

函数多个返回值

如果一个函数要有多个返回值,按照返回值的顺序,写对应顺序的多个变量接收即可。
变量之间用逗号隔开。
支持不同类型的数据return。

1
2
3
4
5
6
7
# 定义一个多返回值的函数
def functionname():
return 1, 2
#调用函数
x ,y = functionname()
print(x) # 1
print(y) # 2

函数说明文档

可以给函数添加说明文档,辅助理解函数的作用。
通过多行注释的形式,对函数进行说明解释,内容应写在函数体之前。

1
2
3
4
5
6
7
8
9
10
# 定义一个函数
def functionname(x , y):
"""
函数说明介绍
:param x 用于解释参数x
:param y 用于解释参数y
:return 用于解释返回值
"""
函数体
return 返回值

函数的嵌套调用

所谓函数嵌套调用指在一个函数中,调用另外一个函数。
函数嵌套调用执行流程是:函数A中执行到调用函数B的语句,会将函数B全部执行完成后,继续执行函数A的剩余内容。

变量的作用域

变量作用域指的是变量的作用范围(变量在哪里可用,在哪里不可用)。
主要分为两类:局部变量和全局变量。

局部变量

局部变量是定义在函数体内部的变量,即只在函数体内部生效。
局部变量的作用:在函数体内部,临时保存数据,即当函数调用完成后则销毁局部变量。
变量total是定义在a函数内部的变量,在函数外部访问则立即报错。

1
2
3
4
5
6
def a(arg1 ,arg2):
total = arg1 + arg2 # total在这里是局部变量.
print("函数内是局部变量 : ", total) # 函数内是局部变量 : 5
return total
a(1,4)
print(total) # NameError: name 'total' is not defined

全局变量

全局变量指的是在函数体内、外都能生效的变量。
变量total是定义在a函数外的变量,可以在整个程序范围内访问。

1
2
3
4
5
6
7
8
# 定义一个全局变量
total = 0
def a(arg1 ,arg2):
total = arg1 + arg2 # total在这里是局部变量.
print("函数内是局部变量 : ", total) # 函数内是局部变量 : 5
return total
a(1,4)
print(total) # 0

global关键字

使用global关键字可以在函数内部声明变量为全局变量。

1
2
3
4
5
6
7
8
total = 0
def a(arg1 ,arg2):
global total # 声明变量为全局变量
total = arg1 + arg2
print("函数内是局部变量 : ", total) # 函数内是局部变量 : 5
return total
a(1,4)
print(total) # 5

匿名函数

函数作为参数传递

函数本身是可以作为参数,传入另一个函数中进行使用的。将函数传入的作用在于传入计算逻辑,而非传入数据。

1
2
3
4
5
6
7
8
def functional1(comp):
comp1 = comp(1, 2)
print(comp1)

def comp(x, y):
return x + y

functional1(comp) # 3

lambda匿名函数

匿名函数使用lambda关键字进行定义。
匿名函数用于临时构建一个函数,只用一次的场景。
匿名函数的定义中,函数体只能写一行代码,如果函数体要写多行代码,不可用lambda匿名函数,应使用def定义带名函数。

定义语法:lambda 传入参数 :函数体(一行代码)

  • lambda是关键字,表示定义匿名函数
  • 传入参数表示匿名函数的形式参数,如x, y表示接收2个形式参数
  • 函数体,就是函数的执行逻辑,要注意:只能写一行,无法写多行代码
1
2
3
4
5
def functional1(comp):
comp1 = comp(1, 2)
print(comp1)
# 通过lambda关键字,传入一个一次性使用的lambda匿名函数
functional1(lambda x , y :x + y) # 3

数据容器

Python中的数据容器指的是,一种可以容纳多份数据的数据类型,容纳的每一份数据称之为一个元素。每一个元素,可以是任意类型的数据,如字符串、数字、布尔等。

数据容器根据特点的不同,如:是否支持重复元素、是否可以修改、是否有序等,分为5类,分别是:列表(list)、元组(tuple)、字符串(str)、集合(set)、字典(dict)

数据容器:list(列表)

列表的定义

列表是最常用的Python数据类型,列表内的每一个数据,称之为元素,以[]作为标识,列表内每一个元素之间用,逗号隔开。

创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可。如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 字面量
[元素1, '元素2', 元素3]
# 定义变量
变量名1 = ['元素1', '元素2', 3]
# 定义空列表
变量名2 = []
变量名3 = list()
# 嵌套列表
变量名4 = [['元素1', '元素2', 3],[True, 2]]

print(变量名1) # ['元素1', '元素2', 3]
print(变量名2) # []
print(type(变量名3)) # <class 'list'>
print(变量名4) # [['元素1', '元素2', 3], [True, 2]]
print(type(变量名4)) # <class 'list'>

列表的特点:

  • 列表可以一次存储多个数据(263 - 1
  • 可以容纳不同类型的元素,支持嵌套。
  • 数据是有序存储的(有下标序号)
  • 允许重复数据存在
  • 可以修改(增加或删除元素等)

列表的下标

可使用列表名[下标索引]从列表中取出特定位置的数据,列表中的每一个元素,都有其位置下标索引,同样你可使用方括号的形式截取字符。

  • 从前向后的方向,编号从0开始递增(0、1、2、3……)
  • 从后向前的方向,编号从-1开始递减(-1、-2、-3……)
  • 如果列表是嵌套的列表,同样支持下标索引
  • 要注意下标索引的取值范围,超出范围无法取出元素,并且会报错IndexError
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
变量名1 = ['元素1', '元素2', 3, 4]
变量名4 = [['元素1', '元素2', 3],[True, 2]]

# 获取正向索引号1的元素
print(变量名1[1]) # 元素2
# 获取反向索引号-1的元素
print(变量名1[-1]) # 4
#截取元素,从1索引开始,截取到3索引,不包含3索引
print("变量名1[1:3]:", 变量名1[1:3]) # 变量名1[1:3]: ['元素2', 3]
# 获取内层第一个列表
print(变量名4[0]) # ['元素1', '元素2', 3]
# 获取内层第一个列表的第一个元素
print(变量名4[0][0]) # 元素1
# 获取内层第一个列表的第一个元素的类型
print(type(变量名4[0][0])) # <class 'str'>

列表的常用操作

列表的查询功能(方法)

查找指定元素在列表中的下标,如果找不到,报错ValueError
语法:列表名.index(元素)

1
2
3
4
5
6
7
变量名1 = ['元素1', '元素2', 3, 4]
变量名4 = [['元素1', '元素2', 3],[True, 2]]

print(变量名1.index(3)) # 2
print(变量名4[0].index("元素1")) # 0
print(变量名4.index("元素1")) # ValueError: '元素1' is not in list
print(变量名4.index("3")) # ValueError: '3' is not in list

列表的修改功能

修改特定位置(索引)的元素值:
语法:列表名[下标] = 值
可以使用如上语法,直接对指定下标(正向、反向下标均可)的值进行重新赋值(修改)。

1
2
3
4
5
6
7
8
变量名1 = ['元素1', '元素2', 3, 4]
变量名4 = [['元素1', '元素2', 3],[True, 2]]

变量名1[1] = 2
print(变量名1) # ['元素1', 2, 3, 4]

变量名4[0][-1] = '字符3'
print(变量名4[0]) # ['元素1', '元素2', '字符3']

列表的插入功能(方法)

在指定的下标位置,插入指定的元素
语法:列表名.insert(下标, 元素)

1
2
3
4
5
6
7
变量名1 = ['元素1', '元素2', 3, 4]
变量名2 = ['元素1', '元素2', 3, 4]

变量名1.insert(1,"新增元素")
print(变量名1) # ['元素1', '新增元素', '元素2', 3, 4]
变量名2.insert(1,["新增元素",3,5])
print(变量名2) # ['元素1', ['新增元素', 3, 5], '元素2', 3, 4]

列表的追加功能(方法)

将指定元素,追加到列表的尾部
语法:列表名.append(元素)

将其它数据容器的内容取出,依次追加到列表尾部
语法:列表名.extend(其它数据容器)

1
2
3
4
5
6
7
8
9
10
变量名1 = ['元素1', '元素2', 3, 4]
变量名2 = ['元素1', '元素2', 3, 4]

变量名1.append("新增元素")
print(变量名1) # ['元素1', '元素2', 3, 4, '新增元素']
变量名2.append(["新增元素",1,2])
print(变量名2) # ['元素1', '元素2', 3, 4, ['新增元素', 1, 2]]

变量名1.extend(变量名2)
print(变量名1) # ['元素1', '元素2', 3, 4, '新增元素', '元素1', '元素2', 3, 4, ['新增元素', 1, 2]]

列表的删除功能(方法)

删除指定的下标位置的元素
语法1: del 列表名[下标]
语法2:列表名.pop(下标)

删除某元素在列表中的第一个匹配项
语法:列表名.remove(元素)

清空列表内容
语法:列表名.clear()

1
2
3
4
5
6
7
8
9
10
11
变量名1 = ['元素1', '元素2', 3, 4, 5, [1, 3, 5]]

del 变量名1[0]
print(变量名1) # ['元素2', 3, 4, 5, [1, 3, 5]]
变量名1.pop(0)
print(变量名1) # [3, 4, 5, [1, 3, 5]]
变量名1.remove(5)
print(变量名1) # [3, 4, [1, 3, 5]]
变量名1.clear()
print(变量名1) # []

列表的统计功能(方法)

统计某元素在列表内的数量
语法:列表名.count(元素)

统计列表内,有多少元素
语法:len(列表名)

1
2
3
4
5
6
7
8
9
10
11
12
变量名1 = ['元素1', '元素2', 3, 4]
变量名2 = ['元素1', '元素2', 3, 4]
# 变量名1.append(变量名2) # ['元素1', '元素2', 3, 4, ['元素1', '元素2', 3, 4]]
变量名1.extend(变量名2) # ['元素1', '元素2', 3, 4, '元素1', '元素2', 3, 4]
变量名3 = ['元素1', '元素2', 3, 4,['元素1', '元素2', 3, 4]]

print(变量名1) # ['元素1', '元素2', 3, 4, '元素1', '元素2', 3, 4]
print(变量名3) # ['元素1', '元素2', 3, 4, ['元素1', '元素2', 3, 4]]
print(变量名1.count(3)) # 2
print(len(变量名1)) # 8
print(变量名3.count(3)) # 1
print(len(变量名3)) # 5

列表的遍历

将容器内的元素依次取出,并处理,称之为遍历操作。
可以使用while或for循环遍历列表的元素。

while循环,遍历列表元素

使用while循环,通过列表名[下标]的方式取出列表的元素。

  • 定义一个变量表示下标,从0开始
  • 循环条件为下标值 < 列表的元素数量
1
2
3
4
5
6
list = [1, 3, 4, 5]
index = 0
while index < len(list):
元素 = list[index]
print(元素)
index += 1

for循环,遍历列表元素

对比while,for循环更加适合对列表等数据容器进行遍历。

  • 从容器内,依次取出元素并赋值到临时变量上。
  • 在每一次的循环中,可对临时变量(元素)进行处理。
1
2
3
list = [1, 3, 4, 5]
for i in list:
print(i)

数据容器:tuple(元组)

元组的定义

定义元组使用小括号,且使用逗号隔开各个数据,数据可以是不同的数据类型。
元组也支持嵌套。
元组只有一个数据,这个数据后面要添加逗号,否则不是元组类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 字面量
(元素1, '元素2', 元素3)
# 定义变量
变量名1 = ('元素1', '元素2', 3)
# 定义空元组
变量名2 = ()
变量名3 = tuple()
# 嵌套元组
变量名4 = (('元素1', '元素2', 3),(True, 2))
变量名5 = ('元素1')
变量名6 = ('元素1',)

print(变量名1) # ('元素1', '元素2', 3)
print(变量名2) # ()
print(type(变量名3)) # <class 'tuple'>
print(变量名4) # (('元素1', '元素2', 3), (True, 2))
print(变量名4[0][0]) # 元素1
print(type(变量名4)) # <class 'tuple'>
print(type(变量名5)) # <class 'str'>
print(type(变量名6)) # <class 'tuple'>

元组的特点:

  • 可以容纳多个数据
  • 可以容纳不同类型的数据
  • 数据是有序存储的(下标索引)
  • 允许重复数据存在
  • 不可以修改(增加或删除元素等)
  • 支持for循环

元组的下标

可使用元组名[下标索引]从元组中取出特定位置的数据,元组中的每一个元素,都有其位置下标索引,同样你可使用方括号的形式截取字符。

  • 从前向后的方向,编号从0开始递增(0、1、2、3……)
  • 从后向前的方向,编号从-1开始递减(-1、-2、-3……)
  • 如果元组是嵌套的元组,同样支持下标索引
  • 要注意下标索引的取值范围,超出范围无法取出元素,并且会报错IndexError
1
2
3
4
5
6
7
变量名1 = ('元素1', '元素2', 3, 4)
变量名4 = [['元素1', '元素2', 3],[True, 2]]

# 获取正向索引号1的元素
print(变量名1[1]) # 元素2
# 获取反向索引号-1的元素
print(变量名1[-1]) # 4

元组的相关操作

元组由于不可修改的特性,所以其操作方法非常少。

元组的查询功能(方法)

查找指定元素在元组中的下标,如果找不到,报错ValueError
语法:列表名.index(元素)

1
2
3
4
5
6
7
变量名1 = ('元素1', '元素2', 3, 4)
变量名4 = (('元素1', '元素2', 3),(True, 2))

print(变量名1.index(3)) # 2
print(变量名4[0].index("元素1")) # 0
print(变量名4.index("元素1")) # ValueError: tuple.index(x): x not in tuple
print(变量名4.index("3")) # ValueError: tuple.index(x): x not in tuple

元组的统计功能(方法)

统计某元素在元组内的数量
语法:元组名.count(元素)

统计元组内,有多少元素
语法:len(元组名)

1
2
3
4
5
6
7
变量名1 = ('元素1', '元素2', 3, 4, ('元素1', '元素2', 3, 4))
变量名2 = ('元素1', '元素2', 3, 4, '元素1', '元素2', 3, 4)

print(变量名1.count(3)) # 1
print(len(变量名1)) # 5
print(变量名2.count(3)) # 2
print(len(变量名2)) # 8

元组的修改操作

  • 不可以修改元组的内容,否则会直接报错`TypeError
  • 可以修改元组内的list的内容(修改元素、增加、删除、反转等),但不可以替换list为其它list或其它类型

元组的遍历

可以使用while或for循环遍历元组的元素。

while循环,遍历元组元素

1
2
3
4
5
6
tup = (1, 3, 4, 5)
index = 0
while index < len(tup):
元素 = tup[index]
print(元素)
index += 1

for循环,遍历元组元素

1
2
3
tup = (1, 3, 4, 5)
for i in tup:
print(i)

数据容器:str(字符串)

字符串是字符的容器,一个字符串可以存放任意数量的字符。

作为数据容器,字符串有如下特点:

  • 只可以存储字符串
  • 长度任意(取决于内存大小)
  • 支持下标索引
  • 允许重复字符串存在
  • 不可以修改(增加或删除元素等)
  • 支持for循环

字符串的下标

和其它容器一样,字符串也可以通过下标进行访问。

  • 从前向后,下标从0开始
  • 从后向前,下标从-1开始
1
2
3
4
5
str1 = 'hello,world'
# str1[1] =1 # TypeError: 'str' object does not support item assignment

print(str1[1]) # e
print(str1[-1]) # d

字符串的常用操作

字符串的查询功能(方法)

查找指定元素在列表中的下标,如果找不到,报错ValueError
语法:字符串.index(元素)

1
2
3
4
str1 = '111'

print(str1.index("1")) # 0
print(str1.index("2")) # ValueError: substring not found

字符串的比较功能

  • 从头到尾,一位位进行比较,其中一位大,后面就无需比较。
  • 单个字符之间通过ASCII码表,确定字符对应的码值数字来确定大小。

字符串的替换功能(方法)

将字符串内的全部:字符串1替换为字符串2,不是修改字符串本身,而是得到了一个新字符串。
语法:字符串.replace(字符串1,字符串2)

1
2
3
4
5
str1 = 'hello,world'
str2 = str1.replace('l','w')

print(str1) # hello,world
print(str2) # hewwo,worwd

字符串的分割功能(方法)

按照指定的分隔符字符串,将字符串划分为多个字符串,并存入列表对象中,字符串本身不变,而是得到了一个列表对象。
语法:字符串.split(分隔符字符串)

1
2
3
4
5
6
str1 = 'hello,world'
list = str1.split(',')

print(str1) # hello,world
print(list) # ['hello', 'world']
print(type(list)) # <class 'list'>

字符串的规整功能(方法)

去前后空格。
语法:字符串.strip()

去除前后指定字符串,若传入的是'12' ,其实就是:'1''2'都会移除,是按照单个字符处理。
语法:字符串.strip(字符串)

1
2
3
4
5
str1 = '    hello,world     '
str2 = '-!hello,world--'

print(str1.strip()) # hello,world
print(str2.strip("-!")) # hello,world

字符串的统计功能(方法)

统计字符串中某字符串的出现次数
语法:字符串.count(字符串)

统计字符串的长度
语法:len(字符串)

1
2
3
4
5
6
str1 = '    hello,world     ' # 左边四个空格,右边五个空格
str2 = '123 !@# qwe QWE 中文' # 数字、字母、符号、空格、中文均算作1个字符

print(str1.count(' ')) # 9
print(str1.count(' ')) # 4
print(len(str2)) # 18

字符串的遍历

可以使用while或for循环遍历字符串的元素。

while循环,遍历字符串

1
2
3
4
5
6
str1 = 'hello,world'
index = 0
while index < len(str1):
元素 = str1[index]
print(元素)
index += 1

for循环,遍历字符串

1
2
3
str1 = 'hello,world'
for i in str1:
print(i)

数据容器(序列)的切片

序列

序列是指:内容连续、有序,可使用下标索引的一类数据容器。
列表、元组、字符串,均可以可以视为序列。

切片

切片:从一个序列中,取出一个子序列。
序列支持切片,即:列表、元组、字符串,均支持进行切片操作。
语法:序列[起始下标:结束下标:步长]
表示在序列中,从指定位置开始,依次取出元素,到指定位置结束,此操作不会影响序列本身,而是会得到一个新序列

  • 起始下标表示从何处开始,可以留空,留空视作从头开始。
  • 结束下标(不含)表示何处结束,可以留空,留空视作截取到结尾。
  • 步长表示,依次取元素的间隔。
    • 步长1表示,一个个取元素。
    • 步长2表示,每次跳过1个元素取。
    • 步长N表示,每次跳过N-1个元素取。
    • 步长为负数表示,反向取(注意,起始下标和结束下标也要反向标记)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
my_list = [1, 2, 3, 4, 5]
new_list1 = my_list[1:4] # 下标1开始,下标4(不含)结束,步长1
print(new_list1) # [2, 3, 4]
new_list2 = my_list[:-2] # 下标0开始,下标倒数第二个(不含)结束,步长1
print(new_list2) # [1, 2, 3]
my_tuple = (1, 2, 3, 4, 5)
new_tuple = my_tuple[:] # 从头开始,到最后结束,步长1
print(new_tuple) # (1, 2, 3, 4, 5)
my_list = [1, 2, 3, 4, 5]
new_list = my_list[::2] # 从头开始,到最后结束,步长2
print(new_list) # [1, 3, 5]
my_str = "12345"
new_str = my_str[:4:2] # 从头开始,到下标4(不含)结束,步长2
print(new_str) # 13

my_str = "12345"
new_str = my_str[::-1] # 从头(最后)开始,到尾结束,步长-1(倒序)
print(new_str) # 54321
my_list = [1, 2, 3, 4, 5]
new_list = my_list[3:1:-1] # 从下标3开始,到下标1(不含)结束,步长-1(倒序)
print(new_list) # [4, 3]
my_tuple = (1, 2, 3, 4, 5)
new_tuple = my_tuple[:1:-2] # 从头(最后)开始,到下标1(不含)结束,步长-2(倒序)
print(new_tuple) # (5, 3)

数据容器:set(集合)

集合的定义

定义集合使用大括号,且使用逗号隔开各个数据,数据可以是不同的数据类型。

1
2
3
4
5
6
7
8
9
10
# 字面量
{元素1, '元素2', 元素3}
# 定义变量
变量名1 = {'元素1', '元素2', 3}
# 定义空集合
变量名2 = set()

print(变量名1) # {3, '元素1', '元素2'}
print(变量名2) # set()
print(type(变量名2)) # <class 'set'>

集合的特点:

  • 可以容纳多个数据
  • 可以容纳不同类型的数据
  • 数据是无序存储的(不支持下标索引)
  • 不允许重复数据存在
  • 可以修改(增加或删除元素等)
  • 支持for循环

集合的常用操作

集合的插入功能(方法)

将指定元素,添加到集合内
语法:集合.add(元素)

1
2
3
4
变量名1 = {'元素1', '元素2', 3}

变量名1.add(1)
print(变量名1) # {'元素2', 1, 3, '元素1'}

集合的修改功能(方法)

取出集合1和集合2的差集(集合1有而集合2没有的),将得到一个新集合,集合1和集合2不变。
语法:集合1.difference(集合2)

对比集合1和集合2,在集合1内,删除和集合2相同的元素,集合1被修改,集合2不变。
语法:集合1.difference_update(集合2)

将集合1和集合2组合成新集合,得到新集合,集合1和集合2不变
语法:集合1.union(集合2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
变量名1 = {'元素1', '元素2', 3}
变量名2 = {'元素1', '元素2', 4}

difference = 变量名1.difference(变量名2)
print(变量名1) # {'元素1', '元素2', 3}
print(变量名2) # {'元素2', '元素1', 4}
print(difference) # {3}

变量名1.difference_update(变量名2)
print(变量名1) # {3}
print(变量名2) # {'元素1', '元素2', 4}

union = 变量名1.union(变量名2)
print(union) # {'元素1', 3, '元素2', 4}
print(变量名1) # {3}
print(变量名2) # {'元素2', 4, '元素1'}

集合的删除功能(方法)

将指定元素,从集合内移除,集合本身被修改,移除了元素
语法:集合.remove(元素)

从集合中随机取出一个元素,会得到一个元素的结果。同时集合本身被修改,元素被移除
语法:集合.pop()

清空集合,集合本身将被清空
语法:集合.clear()

1
2
3
4
5
6
7
8
9
10
11
变量名1 = {'元素1', '元素2', 3}

# 变量名1.remove(1) # KeyError: 1
变量名1.remove(3)
pop = 变量名1.pop()
print(pop) # 元素1
print(变量名1) # {'元素2'}
变量名1.clear()
print(变量名1) # set()
pop = 变量名1.pop()
print(pop) # KeyError: 'pop from an empty set'

集合的统计功能(方法)

统计集合内有多少元素,得到一个整数结果
语法:len(集合)

1
2
3
变量名1 = {'元素1', '元素2', 3}

print(len(变量名1)) # 3

集合的遍历

集合同样支持使用for循环遍历,但因为集合不支持下标索引,所以不支持使用while循环。

for循环,遍历集合

1
2
3
变量名1 = {'元素1', '元素2', 3}
for i in 变量名1:
print(i)

数据容器:dict(字典)

字典的定义

字典的每个键值对key:value用冒号:分割,每个键值对之间用逗号,分割,整个字典包括在花括号{} 中,字典可嵌套,字典的Key和Value可以是任意数据类型(Key不可为字典),格式如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 字面量
{key : value , key : value , ... , key : value}
# 定义变量
变量名1 = {key : value , key : value , ... , key : value}
# 定义空字典
变量名2 = {}
变量名3 = dict()
# 定义字典嵌套
变量名1 = {
key : {key : value , key : value , ... , key : value} ,
key : {key : value , key : value , ... , key : value} ,
key : {key : value , key : value , ... , key : value}
}

print(变量名1)
print(变量名2) # {}
print(type(变量名2)) # <class 'dict'>

字典的特点:

  • 可以容纳多个数据
  • 可以容纳不同类型的数据
  • 每一份数据是KeyValue键值对
  • 可以通过Key获取到Value,Key不可重复(重复会覆盖)
  • 不支持下标索引
  • 可以修改(增加或删除更新元素等)
  • 支持for循环,不支持while循环

字典的常用操作

字典数据的获取功能

字典同集合一样,不可以使用下标索引,但是字典可以通过Key值来取得对应的Value
语法:字典名[key]

1
2
3
4
变量名1 = {"key": "value", 1: 111, 2: ["value1", "value2"]}

print(变量名1["key"]) # value
print(变量名1[2]) # ['value1', 'value2']

字典的新增元素功能

新增元素,字典被修改
语法:字典[Key] = Value

1
2
3
4
变量名1 = {"key": "value", 1: 111, 2: ["value1", "value2"]}
变量名1[3] = '新数据'
print(变量名1[3]) # 新数据
print(变量名1) # {'key': 'value', 1: 111, 2: ['value1', 'value2'], 3: '新数据'}

字典的更新元素功能

元素被更新,字典被修改。
注意:字典Key不可以重复,所以对已存在的Key执行上述操作,就是更新Value值
语法:字典[Key] = Value

1
2
3
4
变量名1 = {"key": "value", 1: 111, 2: ["value1", "value2"]}
变量名1[1] = '修改后数据'
print(变量名1[1]) # 修改后数据
print(变量名1) # {'key': 'value', 1: '修改后数据', 2: ['value1', 'value2']}

字典的删除功能(方法)

删除元素,返回指定Key的Value,同时字典被修改,指定Key的数据被删除
语法:字典.pop(Key)

字典被修改,元素被清空
语法:字典.clear()

1
2
3
4
5
6
7
8
9
变量名1 = {"key": "value", 1: 111, 2: ["value1", "value2"]}
pop = 变量名1.pop("key")

print(pop) # value
print(变量名1) # {1: 111, 2: ['value1', 'value2']}

变量名1.clear()

print(变量名1) # {}

字典的获取功能(方法)

得到字典中的全部Key
语法:字典.keys()

1
2
3
4
5
变量名1 = {"key": "value", 1: 111, 2: ["value1", "value2"]}
keys = 变量名1.keys()

print(keys) # dict_keys(['key', 1, 2])
print(变量名1) # {'key': 'value', 1: 111, 2: ['value1', 'value2']}

字典的统计功能(方法)

计算字典内的全部元素(键值对)数量,得到一个整数,表示字典内元素(键值对)的数量
语法:len(字典)

1
2
3
4
5
变量名1 = {"key": "value", 1: 111, 2: ["value1", "value2"]}
i = len(变量名1)

print(i) # 3
print(变量名1) # {'key': 'value', 1: 111, 2: ['value1', 'value2']}

字典的遍历

字典同样支持使用for循环遍历,可通过获取字典中所有key进行遍历,但因为字典不支持下标索引,所以不支持使用while循环。

for循环,遍历集合

1
2
3
变量名1 = {"key": "value", 1: 111, 2: ["value1", "value2"]}
for key in 变量名1.keys():
print(f"键:{key},值:{变量名1[key]}")

数据容器特点对比

列表 元组 字符串 集合 字典
元素数量 支持多个 支持多个 支持多个 支持多个 支持多个
元素类型 任意 任意 仅字符 任意 Key:Value
下标索引 支持 支持 支持 不支持 不支持
重复元素 支持 支持 支持 不支持 不支持
可修改性 支持 不支持 不支持 支持 支持
数据有序
使用场景 可修改、可重复的一批数据记录场景 不可修改、可重复的一批数据记录场景 一串字符的记录场景 不可重复的数据记录场景 以Key检索Value的数据记录场景

数据容器的通用操作

数据容器尽管各自有各自的特点,但是它们也有通用的一些操作。

数据容器的通用遍历操作

在遍历上:

  • 5类数据容器都支持for循环遍历
  • 列表、元组、字符串支持while循环,集合、字典不支持(无法下标索引)

数据容器的通用统计功能

数据容器可以通用非常多的功能方法

  • 统计容器的元素个数,方法len(容器)
  • 统计容器的最大元素,方法max(容器)
  • 统计容器的最小元素,方法min(容器)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
my_list = [1, 2, 3]
my_tuple = (1, 2, 3, 4, 5)
my_str = "helle,world"

print(len(my_list)) # 3
print(len(my_tuple)) # 5
print(len(my_str)) # 11

print(max(my_list)) # 3
print(max(my_tuple)) # 5
print(max(my_str)) # w

print(min(my_list)) # 1
print(min(my_tuple)) # 1
print(min(my_str)) # ,

数据容器的通用转换功能

除了下标索引这个共性外,还可以通用类型转换

  • 将给定容器转换为列表,方法list(容器)
  • 将给定容器转换为字符串,方法str(容器)
  • 将给定容器转换为元组,方法tuple(容器)
  • 将给定容器转换为集合,方法set(容器)

数据容器的通用排序功能

排序后都会得到列表(list)对象。

  • 将给定容器进行排序,方法sorted(容器, [reverse=True])reverse=True表示降序。
1
2
3
4
5
6
7
8
9
10
11
my_list = [["a", 33], ["b", 55], ["c", 11]]

# 排序,基于带名函数
# def choose_sort_key(element):
# return element[1]
#
# my_list.sort(key=choose_sort_key, reverse=True)
# 排序,基于lambda匿名函数
my_list.sort(key=lambda element: element[1], reverse=True)

print(my_list) # [['b', 55], ['a', 33], ['c', 11]]

文件操作

文件的打开

在Python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件,语法如下:

1
2
3
4
# open()函数常用形式是接收三个参数:文件名(file)、模式(mode)、字符编码(encoding)。
open(name, mode, encoding)
# open()函数完整的语法格式
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

参数说明:

  • file:必需,文件路径(相对或者绝对路径)。
  • mode:可选,文件打开模式,常用的模式有:
    • 只读r,以只读方式打开文件。文件的指针将会放在文件的开头,文件若不存在,会提示FileNotFoundError异常。这是默认模式。
    • 写入w,打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,原有内容会被删除。如果该文件不存在,创建新文件。
    • 追加a,打开一个文件用于追加。如果该文件已存在,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
  • buffering:设置缓冲。
  • encoding:编码格式,一般使用utf8。
  • errors:报错级别。
  • newline:区分换行符。
  • closefd:传入的file参数类型。
  • opener:设置自定义开启器,开启器的返回值必须是一个打开的文件描述符。

示例代码:

1
2
3
4
5
# encoding的顺序不是第三位,所以不能用位置参数,用关键字参数直接指定
file_1 = open('python.txt', 'r', encoding='UTF-8')

# 使用open()方法一定要保证关闭文件对象,即调用close()方法。
file_1.close()

with open语法

  • 通过在with open的语句块中对文件进行操作
  • 可以在操作完成后自动关闭close文件,避免遗忘掉close方法
1
2
with open("python.txt", "r") as file_1:
file_1.readlines()

文件的读取

从文件读取指定的字节数,如果未给定或为负则读取所有。
语法:文件对象.read([size])

读取所有行并返回列表,其中每一行的数据为一个元素。若给定sizeint>0,则是设置一次读多少字节,这是为了减轻读取压力。
语法:文件对象.readlines([sizeint])

读取整行,包括 “\n” 字符。
语法:文件对象.readline([size])

for循环读取文件行。
语法:for line in 文件对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
file_1 = open('test', 'r', encoding='UTF-8')

# read = file_1.read(15)
# print(read) # Hello World!\n你好

# readline = file_1.readlines()
# print(readline) # ['Hello World!\n', '你好世界!']

# content = file_1.readline()
# print(f'第一行:{content}') # 第一行:Hello World!
# content = file_1.readline()
# print(f'第二行:{content}') # 第二行:你好世界!

# 关闭文件
file_1.close()

# for循环读取文件行,每一个line临时变量,就记录了文件的一行数据
for line in open('test', 'r', encoding='UTF-8'):
print(line)

文件的关闭

关闭文件。关闭后文件不能再进行读写操作。如果不调用close,同时程序没有停止运行,那么这个文件将一直被Python程序占用。
语法:文件对象.close()

文件的写入

将字符串写入文件,返回的是写入的字符长度。
语法:文件对象.write(str)

刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。
语法:文件对象.flush()

1
2
3
4
5
6
7
8
# 1. 打开文件
f = open('python.txt', 'w')
# 2.文件写入
f.write('hello world')
# 3. 内容刷新
f.flush()
# 4. 关闭文件,close()方法带有flush()方法的功能
f.close()

注意事项:

  • 可以使用\n来写出换行符。
  • 直接调用write,内容并未真正写入文件,而是会积攒在程序的内存中,称之为缓冲区。
  • 当调用flush的时候,内容会真正写入文件。
  • 这样做是避免频繁的操作硬盘,导致效率下降(内存中缓存数据,一次性写入磁盘)。

文件的追加

追加写入文件使用open函数的a模式进行写入
追加写入的方法有:

  • wirte(),写入内容
  • flush(),刷新内容到硬盘中
1
2
3
4
5
6
7
8
# 1. 打开文件,通过a模式打开即可
f = open('python.txt', 'a')
# 2.文件写入
f.write('hello world')
# 3. 内容刷新
f.flush()
# 4. 关闭文件,close()方法带有flush()方法的功能
f.close()

异常处理

异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
一般情况下,在Python无法正常处理程序时就会发生一个异常。
当Python脚本发生异常时需捕获处理它,否则程序会终止执行。

异常的捕获方法

在可能发生异常的地方,进行捕获。
当异常出现的时候,提供解决方式,而不是任由其导致程序无法运行。
捕捉异常可以使用try/except语句。
try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。

捕获常规异常

1
2
3
4
try:
可能发生错误的代码
except:
如果出现异常执行的代码

捕获指定异常

1
2
3
4
try:
print(name)
except NameError as e:
print('name变量名称未定义错误')

注意:

  • 如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常。
  • 一般try下方只放一行尝试执行的代码。

捕获多个异常

当捕获多个异常时,可以把要捕获的异常类型的名字,放到except 后,并使用元组的方式进行书写。

1
2
3
4
try:
print(1/0)
except (NameError, ZeroDivisionError):
print('ZeroDivision错误...')

捕获异常并输出描述信息

1
2
3
4
try:
print(num)
except (NameError, ZeroDivisionError) as e:
print(e)

捕获所有异常

1
2
3
4
try:
print(name)
except Exception as e:
print(e)

异常else

else表示的是如果没有异常要执行的代码。
如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。

1
2
3
4
5
6
try:
print(1)
except Exception as e:
print(e)
else:
print('我是else,是没有异常的时候执行的代码')

异常的finally

finally表示的是无论是否异常都要执行的代码,例如关闭文件。

1
2
3
4
5
6
7
8
try:
f = open('test.txt', 'r')
except Exception as e:
f = open('test.txt', 'w')
else:
print('没有异常,真开心')
finally:
f.close()

异常的传递

异常是具有传递性的。
函数a中发生异常,并且没有捕获处理这个异常的时候, 异常会传递到函数b,当函数b也没有捕获处理这个异常的时候,main函数会捕获这个异常, 这就是异常的传递性。
当所有函数都没有捕获异常的时候, 程序就会报错。
利用异常具有传递性的特点,当想要保证程序不会因为异常崩溃的时候,就可以在main函数中设置异常捕获, 由于无论在整个程序哪里发生异常, 最终都会传递到main函数中, 这样就可以确保所有的异常都会被捕获。

1
2
3
4
5
6
7
8
9
10
def a():
print(1/0)
def b():
a()
def main():
try:
b()
except Exception as e :
print(e)
main() # division by zero

模块

Python 模块(Module),是一个Python文件,以.py结尾,模块能定义函数,类和变量,模块里也能包含可执行的代码。一般情况下,模块的名字就是文件名(不包括扩展名.py)。
Python中有很多各种不同的模块,,每一个模块都可以帮助快速的实现一些功能,比如实现和时间相关的功能就可以使用time模块。
可以认为一个模块就是一个工具包,每一个工具包中都有各种不同的工具供程序使用进而实现各种不同的功能。

模块的导入

模块在使用前需要先导入,导入的语法如下:

[from 模块名] import [模块 | 类 | 变量 | 函数 | *] [as 别名]

一个模块只会被导入一次,不管执行了多少次import。这样可以防止导入模块被一遍又一遍地执行。
当导入多个模块的时候,且模块内有同名功能, 当调用这个同名功能的时候,调用到的是后面导入的模块的功能。

常用的组合形式如:

  • import 模块名
  • from 模块名 import 类、变量、方法等
  • from 模块名 import *
  • import 模块名 as 别名
  • from 模块名 import 功能名 as 别名

import 语句

模块定义好后,可以使用import语句来引入模块,语法如下:

import module1[, module2[,... moduleN]]

比如要引用模块time,就可以在文件最开始的地方用import time来引入。在调用time模块中的函数时,必须这样引用time.函数名()

from…import 语句

from 语句可从模块中导入一个指定的部分到当前命名空间中。语法如下:

from modname import name1[, name2[, ... nameN]]

比如要导入time模块中的sleep方法,就可以在文件最开始的地方用from time import sleep来引入。这个声明不会把整个time模块导入到当前的命名空间中,它只会将time里的 sleep单个引入到执行这个声明的模块的全局符号表。在调用time模块中的sleep函数时,可直接引用sleep()

from 模块名 import *

把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明:

from modname import *

比如要导入time模块中所有的方法,就可以在文件最开始的地方用from time import *来引入。在调用time模块中的sleep函数时,可直接引用sleep()

as定义别名

1
2
3
4
5
6
7
# 模块定义别名
import 模块名 as 别名
别名.函数名()

# 功能定义别名
from 模块名 import 功能 as 别名
别名()

自定义模块

每个Python文件都可以作为一个模块,模块的名字就是文件的名字。也就是说自定义模块名必须要符合标识符命名规则。

创建my_module1.py文件,自定义my_module1模块,并定义test函数。

1
2
def test(a, b):
print(a + b)

测试类中引入自定义my_module1模块,并测试test函数。

1
2
3
import my_module1

my_module1.test(1, 2)

name变量

当在模块文件my_module1.py文件中添加测试代码test(1,1),会导致无论是当前文件,还是其他已经导入了该模块的文件,在运行的时候都会自动执行test函数的调用。
可使用__main__处理模块的重复调用。

修改my_module1.py文件,使用if进行判断。

1
2
3
4
5
6
7
def test(a, b):
print(a + b)
# 全局变量__name__存放的就是模块的名字,如'my_module1'
# 当一个模块作为脚本执行时,__name__的值不再是模块名,而是字符串'__main__'
# if判断表示,只有当程序是直接执行的才会进入if内部,如果是被导入的,则if无法进入
if __name__ == '__main__':
test(1, 3)

__all__变量

如果一个模块文件中有__all__变量,当使用from xxx import *导入时,只能导入这个列表中的元素。

修改my_module1.py文件,设置__all__变量,当其他类使用from xxx import *导入my_module1模块时,仅能导入__all__这个变量中定义的方法。

1
2
3
4
5
6
7
__all__ = ['test1']

def test1(a, b):
print(a + b

def test2(a, b):
print(a + b)

包是一个分层次的文件目录结构,它定义了一个由模块及子包,和子包下的子包等组成的Python的应用环境。

简单来说,包就是文件夹,但该文件夹下必须存在__init__.py文件,该文件的内容可以为空。__init__.py用于标识当前文件夹是一个包。

当模块文件越来越多时,包可以帮助管理这些模块。包的作用就是包含多个模块,但包的本质依然是模块。

包的创建

新建包([New]->[Python Package])后,包内部会自动创建__init__.py文件,这个文件控制着包的导入行为。
新建包package_mod,包下包含mod1.pymod2.py两个模块,__init__.py文件为新建包后自动生成的文件,test.py 为测试调用包的代码,目录结构如下:

1
2
3
4
5
test.py
package_mod
|-- __init__.py
|-- mod1.py
|-- mod2.py

导入包

使用import导入

1
2
3
import 包名.模块名

包名.模块名.目标

使用from导入

必须在__init__.py文件中添加__all__ = [],控制允许导入的模块列表。
__all__针对的是 from ... import * 这种方式,对import xxx这种方式无效。

1
2
3
from 包名 import *

模块名.目标

安装第三方包

在Python程序的生态中,有许多非常多的第三方包(非Python官方),可以极大的提高开发效率,如:

  • 科学计算中常用的:numpy包
  • 数据分析中常用的:pandas包
  • 大数据计算中常用的:pyspark、apache-flink包
  • 图形可视化常用的:matplotlib、pyecharts
  • 人工智能常用的:tensorflow

但是由于是第三方,所以Python没有内置,所以需要安装它们才可以导入使用。

安装第三方包 - pip

只需要使用Python内置的pip程序即可。在命令提示符程序里面输入pip install 包名称,即可通过网络快速安装第三方包。

由于pip是连接的国外的网站进行包的下载,所以有的时候会速度很慢。

使用pip的时候加参数-i,可以临时使用国内镜像,让其连接国内的网站进行包的安装,pip install -i 国内镜像 包名称
如使用清华大学的镜像https://pypi.tuna.tsinghua.edu.cn/simple、阿里云的镜像http://mirrors.aliyun.com/pypi/simple来加快下载速度。

安装第三方包 - PyCharm

  1. 打开Python Interpreter。在Pycharm 右下角点击Interpreter Setting或者在Settings->Project:项目名->Python Interpreter
  2. 打开Available Packages。点击Install或使用快捷键Alt + Insert
  3. 输入要安装的第三方报名,进行安装

若搜索下载超时,需配置PyCharm底部的工具窗口栏中的Python Packages中的Manage repositories,设置国内镜像。