目录
Python基本使用语法
老生常谈
Python中的注释
Python变量
定义变量
变量类型
Python变量的特点
Python中的输入与输出
Python中的运算符
算术运算符
/和//
**运算符
关系运算符
逻辑运算符
赋值运算符
Python运算符优先级
Python分支语句
if语句和if-else语句
if-else if-else语句
Pass语句
Python循环语句
while循环
for循环
break语句和continue语句
循环与else语句
Python函数
定义与调用函数
函数返回语句
函数作用域
嵌套作用域不存在
函数参数默认值
关键字参数传递
列表
定义列表
列表的访问
列表切片操作
列表遍历
列表元素修改
列表新增元素
列表查找元素
列表删除元素
列表拼接
元组
创建元组
列表和元组的对比与选择
字典
创建字典
查找key
通过key新增/修改value
删除元素
遍历字典元素
取出所有key、value或键值对
合法的key类型
Python文件操作
打开文件
关闭文件
读文件
上下文管理器
Python基本使用语法
老生常谈
在Python中可以使用内置函数print()
打印需要的内容,并且默认情况下print()
函数会换行,使用该函数打印Hello World
# 打印Hello World
print("Hello World")
如果使用了GBK编码作为了注释内容,可能会出现下面的报错:
SyntaxError: Non-UTF-8 code starting with '\xb4' in file <文件路径> on line 1, but no encoding declared; see PEP 263 – Defining Python Source Code Encodings | peps.python.org for details
建议将项目文件的编码改成UTF-8,UTF-8也是Python推荐的编码和解码格式
Python中的注释
在Python中,一共有两种注释方式:
- 行注释:使用
#
,类似于Java中的//
# 单行注释
- 文档字符串注释:使用三个引号(包括单引号
'''
和双引号"""
),成对出现,不可以出现嵌套
'''
多行注释
'''
"""
多行注释
"""
Python变量
定义变量
在Python中,定义变量遵循下面的格式:
变量名 = 内容
# 例如
a = 10
变量类型
在Python中,可以使用type()
函数显示变量的类型
Python中的变量一共有5种基本类型以及其他类型
- 整数
# 整型变量
a = 1
print(a) # 1
print(type(a)) # <class 'int'>
- 浮点数:在Python中,只有
float
一种类型,没有double
类型,但是Python中的float
类型对应着C++中的double
类型
# 浮点型变量
b = 1.1
print(b) # 1.1
print(type(b)) # <class 'float'>
- 字符串:在Python中,可以使用单引号
''
,也可以使用双引号""
包裹字符串内容,可以使用len()
函数获取字符串长度。在Python中,字符串拼接使用+
,与Java和JavaScript语言类似
# 字符串变量
c = "Hello World"
print(c) # Hello World
print(type(c)) # <class 'str'>
# 字符串拼接
print(c + "!") # Hello World!
# 字符串求长度
print(len(c)) # 11
- 布尔类型:在Python中,与JavaScript一样,布尔类型在与数值类型参与运算时,
True
和False
会被分别当作1和0
# 布尔型变量
d = True
print(d) # True
print(type(d)) # <class 'bool'>
# 布尔值与数值运算
print(True + 1); # 2
print(False + 1.0); # 1.0
- 空值类型:在Python中,
None
是NoneType
类型的唯一实例。任何变量都没有办法改变None
的值,因为它是单例(Singleton)。
# 空值变量
e = None
print(e)
print(type(e)) # <class 'NoneType'>
Python变量的特点
大部分情况下,Python的变量满足动态弱类型,即支持在运行时改变变量类型(动态)并且类型不同时一般情况下支持隐式类型转换(弱),例如下面的代码:
# 弱类型变量和动态类型变量
i = 1
print(type(i)) # <class 'int'>
f = 1.1
print(type(f)) # <class 'float'>
# 整型变量赋值给浮点型变量
f = i
print(f) # 1
print(type(f)) # <class 'int'>
s = "Hello World"
f = s
print(f) # Hello World
print(type(f)) # <class 'str'>
Python中的输入与输出
在Python中,使用print
函数进行控制台输出,使用input
函数进行控制台输入,Python的input函数返回的是字符串类型,不论输入的数值类型(整型和浮点数)还是本身就是字符串类型,例如下面的代码:
# 输入的是字符串类型
name = input('请输入您的姓名:')
print(type(name))
print('您输入的姓名是:', name)
输入与输出:
请输入您的姓名:zhangsan
<class 'str'>
您输入的姓名是: zhangsan
# 输入的是数值类型
name = input('请输入您的姓名:')
print(type(name))
print('您输入的姓名是:', name)
输入与输出:
请输入您的姓名:2
<class 'str'>
您输入的姓名是: 2
print
函数不仅能输出字符串类型,也可以输出其他类型,例如:
a = 1
print(a)
如果希望字符串常量和变量一起输出,则可以使用f-string,即带格式的字符串,使用在需要输出的字符串前写上f
,在常量字符串中使用{}
包裹需要输出的变量或者表达式,例如下面的代码:
a = 1
print(f"a的值是:{a}")
因为input()
函数默认返回字符串类型,所以如果需要使用输入的数值进行运算,则需要进行强制类型转换,例如下面的代码:
a = input() # 输入3
b = input() # 输入2
print(f"a+b的值为{int(a) + int(b)}") # 输出5
Python中的运算符
算术运算符
/
和//
对于主要运算符+
、-
、*
和%
来说,使用方法与C++相同,此处需要注意/
和//
(不是C++中的注释)
在Python中,/
计算的是数学中保留小数点后方有效内容的结果,//
计算的是不保留小数点后方有效内容的结果,但是会向下取整,例如下面的代码:
# /和//
a = 10
b = 3
print(a / b) # 3.3333333333333335
print(a // b) # 3
# /和//
a = 10
b = -3
print(a / b) # 3.3333333333333335
print(a // b) # -4
需要注意的是,//
操作符如果左右两侧都是浮点数,计算的结果依旧不保留小数点后有效内容,但是会在小数部分加上.0
,并且向下取整,但是不影响/
,例如下面的代码:
# /和//
a = 10.0
b = -3.0
print(a / b) # 3.3333333333333335
print(a // b) # -4.0
注意,如果使用
/
时,第二操作数为0,则会抛出异常
**
运算符
在Python中,**
表示次方,既可以算整数次方,也可以计算小数次方
# **
print(2 ** 3) # 8
print(2 ** 0.5) # 2.0,相当于求2的算术平方根
关系运算符
基本规则与C++和Java类似。如果关系符合, 则表达式返回 True
;如果关系不符合, 则表达式返回 False
在Python中,关系运算符还可以用于比较字符串,例如下面的代码:
# 关系运算符比较字符串
print("bcd" > "bac") # true
不建议使用关系运算符比较浮点数,因为浮点数的精度问题,比较结果仅供参考,可以考虑在一定误差范围内进行比较
逻辑运算符
基本规则与C++和Java类似,但是在Python中主要用关键字表示对应逻辑:
- and(并且)
- or(或者)
- not(逻辑取反)
赋值运算符
与C++和Java类似,只是在Python中没有自增运算符++
和自减运算符--
Python运算符优先级
运算符 | 描述 |
** | 指数 (最高优先级) |
| 按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@) |
| 乘,除,取模和取整除 |
| 加法减法 |
| 右移,左移运算符 |
| 位 'AND' |
| 位运算符 |
| 比较运算符 |
| 等于运算符 |
| 赋值运算符 |
| 身份运算符 |
| 成员运算符 |
| 逻辑运算符 |
Python分支语句
Python语言是一个严格要求缩进(标准要求4个空格)的语言,其缩进代表层次,同一个层次为一个代码块,在执行程序时,会根据层次判断执行方式
分支基本逻辑和C++相同,下面只讲述Python中的格式
if语句和if-else语句
在Python中,使用下面的格式书写if
语句
if 条件:
执行语句1
执行语句2
执行语句3
# 注意,执行语句1和执行语句2是平级的,执行语句3和if语句块平级
使用下面的格式书写if-else
语句:
if 条件:
执行语句1
执行语句2
else:
执行语句3
例如实例:
# 判断一个数是奇数还是偶数
num = int(input("请输入一个整数:"))
if num % 2 == 0:
print(f"输入的数是{num}")
print(f"{num}是偶数")
else:
print(f"输入的数是{num}")
print(f"{num}是奇数")
print("不论是if还是else都会执行")
输入和输出:
请输入一个整数:5
输入的数是5
5是奇数
不论是if还是else都会执行
if-else if-else
语句
在Python中,也存在else if
语句,但是在代码中,else if
写为elif
,整体语法格式如下:
if 条件1:
执行语句1
elif 条件2:
执行语句2
...
else
执行语句3
例如实例:
# 判断一个数是正数、负数还是零
num = int(input("请输入一个整数:"))
if num > 0:
print(f"输入的数是{num}")
print(f"{num}是正数")
elif num < 0:
print(f"输入的数是{num}")
print(f"{num}是负数")
else:
print(f"输入的数是{num}")
print(f"{num}是0")
print("不论是if还是else都会执行")
输入和输出:
请输入一个整数:-1
输入的数是-1
-1是负数
不论是if还是else都会执行
Pass
语句
在Python中,pass
语句表示空语句,一般用于占位
# pass语句
num = -1
if num > 0:
pass
else:
print("num小于0")
上面的代码等价于:
if num < 0:
print("num小于0")
Python循环语句
基本逻辑与C++和Java类似,下面仅展示Python中的格式
while
循环
在Python中,while循环的基本结构如下:
while 循环判断条件:
循环执行语句1
循环执行语句2
例如实例:
# 打印1 - 10
i = 1
while i <= 10:
print(i)
i += 1
print("while循环同样遵循缩进规则,循环体内的代码要缩进。")
for
循环
在Python中,for循环的基本结构和C++差别比较大,下面是基本结构:
for 迭代变量 in range(起始值, 终止值, (可选)步长)/可迭代对象:
循环执行语句1
循环执行语句2
- 迭代变量:相当于C++中的循环变量,用于控制循环
- 起始值:迭代变量的初始值
- 终止值:迭代变量最大值,注意,最后迭代变量不会等于最大值
- 步长:可以理解为增量,起始值每一次循环需要加步长,默认情况下步长为1,步长也可以为负数
例如实例:
# 打印0 - 11中的偶数
for i in range(0, 11, 2):
print(i)
- 对于
range
部分来说,也可以选择迭代对象为其他类型,例如字符串
# 使用可迭代对象
for i in "Hello World":
print(i)
上面的代码中,使用字符串作为可迭代对象,此时打印的即为每一个字符串中的每一个字符
Python中是没有字符的概念,上面代码中的每一个字符本质还是一个字符串
break
语句和continue
语句
基本逻辑与C++相同,使用方式也基本一致,但是需要遵循Python的格式,可参考pass语句的书写方式
循环与else
语句
在Python中,循环可以结合else
语句,执行逻辑为:当循环未执行完毕时,正常执行循环不执行else
语句,否则执行else
语句,格式如下:
# while和else
while 循环条件:
循环语句1
循环语句2
else
分支语句1
分支语句2
# for和else
for 迭代变量 in range(起始值, 终止值, (可选)步长):
循环语句1
循环语句2
else
分支语句1
分支语句2
需要注意,如果循环是因为break
结束的,则else
语句依旧不会执行
Python函数
定义与调用函数
在Python中,使用下面的格式定义函数:
def 函数名(形参列表):
函数体
返回语句(可选)
例如定义一个加法函数:
def add(a, b):
return a + b
Python中函数的形参和实参个数要一一匹配,否则会报错(不同于JavaScript)
因为Python中的变量动态类型,所以实参可以传递任意类型,例如下面的代码:
# 打印形参值
def print_arg(a):
print(a)
print_arg(1)
print_arg("hello")
print_arg(1.0)
输出结果:
1
hello
1.0
函数返回语句
在Python中,因为变量是动态类型,所以函数不需要指定返回值类型,而用于接收有返回值的函数的变量类型由return
语句返回的值类型进行判断,例如下面的代码:
# 打印形参值
def print_arg(a):
print(a)
return a
ret1 = print_arg(1)
print(type(ret1))
ret2 = print_arg("hello")
print(type(ret2))
ret3 = print_arg(1.0)
print(type(ret3))
输出结果:
1
<class 'int'>
hello
<class 'str'>
1.0
<class 'float'>
在Python中,函数返回值可以有多个,当函数有多个返回值时,用于接收函数返回值的变量的数量必须与函数返回值数量匹配,每一个用于接收函数返回值的变量用,
隔开,例如:
# 返回多个值的函数
def add(a, b):
return a, b, a+b
a, b, ret = add(1, 2)
print(a, b, ret)
如果只想接收某一个返回值,则可以使用下划线_
对不需要接收的返回值进行占位,例如:
# 返回多个值的函数
def add(a, b):
return a, b, a+b
# a, b, ret = add(1, 2)
# print(a, b, ret)
_, ret, _ = add(1, 2)
print(ret) # 只接受第二个返回值
函数作用域
在Python中,尽管没有嵌套作用域,但是有函数作用域,所以定义在函数中的变量不可以被外部作用域访问,例如下面的代码:
# 函数作用域
def add(a, b):
c = 3
return a + b + c
ret = add(1, 2)
print(ret)
# print(c) # NameError: name 'c' is not defined
因为函数存在作用域,此时允许函数内部与外部出现重名的变量,此时当变量出现重名时,会优先访问最近的变量,如果在当前作用域中没有找到需要的变量,则继续向上一级作用域寻找,如果没有找到,则报错,例如:
# 重名变量
a = 1
print(a) # 1
def print_a():
a = 2
print(a) # 2
print_a()
print(a) # 1
# 如果没有a = 2
a = 1
print(a) # 1
def print_a():
# a = 2
print(a) # 1
print_a()
print(a) # 1
上面的效果同样适用于在函数内部定义的一个新的函数,当内部函数想访问外部函数定义和内部函数定义的重名变量时同样遵循上面的规则
# 函数嵌套定义
def outer():
a = 1
def inner():
# a = 2
print(a)
inner()
print(a)
outer() # 1 1
如果在全局作用域中定义的函数想修改全局变量,则需要使用global
关键字
a = 1
print(a) # 1
def print_a():
global a
a = 10
print(a) # 10
print_a()
print(a) # 10
需要注意,global
前不可以出现重名变量,否则会报错为在global
前面声明了重名的变量
嵌套作用域不存在
在C++和Java中,存在嵌套作用域,定义在if
/while
/for
中的变量只可以被当前嵌套作用域访问,但是在Python中,内部定义的变量通常不会创建一个新的作用域,这些变量的作用域仍然是它们所在的最外层非局部作用域
在if
语句中创建一个变量,对比Python和C++的代码执行结果:
在Python中:
# 嵌套作用域
num = 1;
if num > 0:
i = 1
print("num大于0")
else:
print("num小于0")
print(i) # 1,可以访问
在C++中:
#include <iostream>
using namespace std;
int main()
{
int num = 5;
if (num > 0)
{
int i = 0;
cout << num;
}
cout << i; // Error: 'i' was not declared in this scope
return 0;
}
函数参数默认值
本部分类似于C++中的缺省值,同样需要满足从右往左给定缺省值,并且满足从右往左使用缺省参数,具体可以参考C++中的缺省参数
使用实例:
# 参数默认值
def add(a, b=1, c=2):
return a + b + c
ret = add(1)
关键字参数传递
在Python中,默认情况下函数调用时传递实参的顺序与形式参数匹配的顺序相同,即从左往右依次传递实参给形参,但是可以通过指定在传递实参时指定形参和对应的值进行传递,例如:
# 关键字参数
def add(a, b, c):
return a + b + c
ret = add(c=3, a=1, b=2)
ret = add(3, 1, b = 2)
与函数参数默认值一样,使用关键字参数传递需要满足从右往左指定,否则会报错
列表
定义列表
在Python中,列表是一个可以存储数据的数据结构,Python中列表的特点如下:
- 列表中的元素数据类型可以是任意的
- 列表中的元素在插入后可以被修改
- 列表中的元素是无序的
创建列表的方式一共有3种:
- 使用
[]
创建一个列表:如果只使用[]
创建列表,则此时列表为空,如果创建时给定了[]
中的内容,则此时列表中即为给定的内容。格式如下:
列表名 = [初始值1, 初始值2, ...]
# 例如
list_1 = [1, 2, 3, 4, 5]
list_2 = ['a', 'b', 'c', 2, 1]
- 使用
list()
函数进行创建:默认情况下创建一个空列表,也可以将已有的列表作为参数传递给list()
函数,格式如下:
列表名 = list()
# 例如:
list_3 = list()
- 使用
+
操作符将已有的两个列表拼接给一个新列表,格式如下:
新列表 = 已知列表1 + 已知列表2
# 例如
list_3 = list_2 + list_1
列表的访问
在Python中,列表支持使用[]
+下标的方式访问,例如下面的代码:
list_1 = [2, 4, 1, 4, 10]
print(list_1[2]) # 1
如果直接打印列表名,则会显示整个列表的元素
list_1 = [2, 4, 1, 4, 10]
print(list_1) # [2, 4, 1, 4, 10]
如果下标大于当前列表的最后一个元素的下标,此时会抛出越界异常
list_1 = [2, 4, 1, 4, 10]
# 越界异常
print(list_1[5]) # IndexError: list index out of range
但是,Python允许下标为负数,而此时的负号-代表倒数第…个,例如[-1]表示倒数第1个,例如下面的代码:
list_1 = [2, 4, 1, 4, 10]
print(list_1[-1]) # 10
此时计数不再是从0开始,所以倒数第一个在上面的列表是10,倒数第二个是4,以此类推直到倒数第五个为最后一个
同样,如果访问倒数第6个则会报出越界异常
list_1 = [2, 4, 1, 4, 10]
# 越界异常
print(list_1[-6]) # IndexError: list index out of range
列表切片操作
列表切片本质上是取出列表中满足条件的子列表,使用下面的格式进行:
列表名[前边界:后边界:步长(可选步长)]
- 前边界:默认情况下包括前边界下标对应的值,可以省略,省略时默认从列表中的第一个元素开始取直到后边界,同
[0:后边界]
- 后边界:默认情况下不包括后边界下标对应的值,可以省略,省略时默认取到列表中的最后一个元素为止
- 步长:可以省略,默认按照一个元素单位。步长可以为正也可以为负,当步长为正则表示从左往右取,步长为负责表示从右往左取
需要注意,前边界和后边界如果都省略,则取出的列表等同于原列表,如果前边界值和后边界值均不在列表有效下标中,则子列表为空
例如下面的代码:
list_1 = [1,2,3,4,5,6,7,8,9,10]
# 切片
# 省略前边界
print(list_1[:3]) # [1, 2, 3]
print(list_1[0:3]) # [1, 2, 3]
# 省略后边界
print(list_1[3:]) # [4, 5, 6, 7, 8, 9, 10]
# 省略二者
print(list_1[:]) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(list_1[3:7]) # [4, 5, 6, 7]
print(list_1[3:10]) # [4, 5, 6, 7, 8, 9, 10]
# 指定步长
print(list_1[3:7:2]) # [4, 6]
# 逆序
print(list_1[::-1]) # [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
列表遍历
遍历列表可以使用循环遍历,代码如下:
list_1 = [1,2,3,4,5,6,7,8,9,10]
# 遍历列表
# 直接遍历
for i in list_1:
print(i)
# 遍历下标,使用len()求出列表长度
for i in range(len(list_1)):
print(list_1[i])
列表元素修改
可以使用[]
+下标的方式对列表的元素进行修改
list_1 = [1,2,3,4,5,6,7,8,9,10]
# 修改列表元素
list_1[2] = 100
print(list_1) # [1, 2, 100, 4, 5, 6, 7, 8, 9, 10]
列表新增元素
列表新增元素有两种方法:
- 使用
append()
函数:默认在尾部插入 - 使用
insert()
函数:在任意位置插入,第一个参数表示插入位置的下标,第二个参数表示插入的数据
list_1 = [1,2,3,4,5,6,7,8,9,10]
# 添加元素
# append()
list_1.append(200)
print(list_1) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 200]
# insert()
list_1.insert(2, 300)
print(list_1) # [1, 2, 3, 100, 4, 5, 6, 7, 8, 9, 10, 200]
需要注意,如果使用
insert()
函数进行插入,当第一个参数的值大于最后一个元素的下标时,默认在尾部插入
列表查找元素
需要查看列表是否存在某一个元素一共有两种方法
- 使用
in
操作符:该操作符左侧是需要查找的内容,右侧时需要查找的对象,返回值类型为布尔类型
list_1 = [1,2,3,4,5,6,7,8,9,10]
# 查找元素
print(2 in list_1) # True
print(200 in list_1) # False
- 使用
index()
函数:该函数接收一个参数,该参数表示需要查找的内容,函数返回查找的内容在列表中的下标位置,如果列表中不存在查找的内容,则会抛出异常
list_1 = [1,2,3,4,5,6,7,8,9,10]
print(list_1.index(2)) # 1
# 抛出异常
print(list_1.index(200)) # ValueError: 200 is not in list
列表删除元素
删除列表元素一共有两种方法:
- 使用
pop()
函数:该函数不给任何参数时,删除的是列表最后一个元素。该方法支持给定一个参数,该参数代表删除的元素下标。该函数会返回删除的元素
list_1 = [1,2,3,4,5,6,7,8,9,10]
# 删除元素
# pop()
print(list_1.pop()) # 10
print(list_1) # [1,2,3,4,5,6,7,8,9]
print(list_1.pop(2)) # 3
print(list_1) # [1,2,4,5,6,7,8,9]
- 使用
remove()
函数:该函数需要指定一个参数,该参数代表需要删除的内容,该函数返回None
,相当于return;
list_1 = [1,2,3,4,5,6,7,8,9,10]
# 删除元素
# remove()
list_1.remove(2)
print(list_1) # [1,4,5,6,7,8,9]
列表拼接
当需要拼接列表时,使用+
操作符,该操作符左侧和右侧均是待拼接列表的名称,这种方法如果没有新的列表接收则只会作为临时列表,不会改变被拼接的两个列表
list_1 = [1,2,3,4,5,6,7,8,9,10]
list_2 = [11, 12, 13]
# 拼接
print(list_1 + list_2) # [1, 4, 5, 6, 7, 8, 9, 11, 12, 13]
print(list_1) # [1, 4, 5, 6, 7, 8, 9]
print(list_2) # [11, 12, 13]
也可以使用extend()
函数,该函数会将参数中的列表拼接到调用函数的列表,此时改变了调用extend()
函数的列表,而不改变作为参数的列表
list_1 = [1,2,3,4,5,6,7,8,9,10]
list_2 = [11, 12, 13]
# 拼接
list_1.extend(list_2)
print(list_1) # [1, 4, 5, 6, 7, 8, 9, 11, 12, 13]
print(list_2) # [11, 12, 13]
元组
元组和列表基本一样,主要的不同点就是元组不可以修改已经插入的元素,所以列表中对数据进行修改操作的在元组中一律失效,此处提供创建元组的实力
默认情况下,函数的多个返回值也是形成了一个元组
创建元组
创建元组有三种方式:
- 使用
()
创建元组:如果给定初始值,则当前元组中为初始值,否则为空元组(后序无法增加元素) - 使用
tuple()
函数创建元组:默认情况下创建一个空元组,也可以通过列表/元组来构造元组 - 使用
+
操作符将已有元组合并给一个新的元组
tuple_1 = (1, 2, 3)
# 通过列表创建元组
tuple_1 = tuple(list_1)
# 使用已有元组创建新元组
tuple_2 = tuple(4,5,6)
tuple_3 = tuple_1 + tuple_2
列表和元组的对比与选择
列表和元组都是日常开发最常用到的类型. 最核心的操作就是根据[]
来按下标操作
- 在需要表示一个"序列"的场景下, 就可以考虑使用列表和元组
- 如果元素不需要改变, 则优先考虑元组
- 如果元素需要改变, 则优先考虑列表
字典
字典本质是一个哈希表,通过键值对的形式保存数据,所以字典默认情况下是不进行自动排序的
创建字典
类比列表,创建字典也有两种方式:
- 使用
{}
创建字典:该方式如果不添加键值对就是空字典,否则为初始值,字典中的每一个初始值均为键:值
组合,每一个键值对由逗号,
分隔,最后一个键值对可以不需要逗号,格式如下:
字典名 = {
键值对1,
键值对2,
键值对3
}
# 例如
dict_1 = {
"key1": "value1",
"key2": "value2",
}
- 使用
dict()
函数创建字典:该方式默认创建一个空的字典
字典名 = dict()
#例如
dict_2 = dict()
查找key
在Python中查找key
有两种方式:
- 使用
in
操作符:该操作符左侧是查找内容,右侧是字典对象,返回值类型时布尔类型
dict_1 = {
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
# in
print("key1" in dict_1) # True
print("key4" in dict_1) # False
- 使用
[]
:该操作符中不再是下标,而是key
,与C++中的unordered_map使用方式类似,但是不同的是,如果key
不存在与字典中,则会抛出异常(需要与下面的新增进行区分)
dict_1 = {
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
# []
print(dict_1["key1"]) # value1
print(dict_1["key4"]) # KeyError: 'key4'
通过key
新增/修改value
注意,字典在插入了键值对后无法修改键,但是可以通过key
查找,修改对应的value
,但是可以新增元素
新增和修改同C++中的unordered_map类似,代码如下:
dict_1 = {
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
# 新增和修改
# 修改
dict_1["key1"] = "modified_value1"
# 新增
dict_1["key4"] = "value4"
print(dict_1) # {'key1': 'modified_value1', 'key2': 'value2', 'key3': 'value3', 'key4': 'value4'}
删除元素
使用pop()
方法删除即可,给定一个参数,该参数为待删除键值对的key
,该函数会返回删除的元素
dict_1 = {
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
# 删除
print(dict_1.pop("key1"))
print(dict_1) # {'key2': 'value2', 'key3': 'value3'}
遍历字典元素
使用循环进行遍历,推荐for
循环
dict_1 = {
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
# 遍历字典
for key in dict_1:
print(key, dict_1[key])
取出所有key
、value
或键值对
- 取出所有的
key
:使用keys()
函数 - 取出所有的
value
:使用values()
函数 - 取出所有的键值对:使用
items()
函数
dict_1 = {
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
# 取出所有的key
print(dict_1.keys()) # dict_keys(['key1', 'key2', 'key3'])
# 取出所有的value
print(dict_1.values()) # dict_values(['value1', 'value2', 'value3'])
# 取出所有的key-value
print(dict_1.items()) # dict_items([('key1', 'value1'), ('key2', 'value2'), ('key3', 'value3')])
此处出现的dict_keys类型、dict_values类型以及dict_items类型是一种特殊的类型,与元组相似,元组可以使用的方法,这三种类型大部分也同样可以使用
合法的key类型
并不是所有的数据类型都可以作为有效key
,有过哈希表的基础后,可以知道合法的key
必须满足可以可以计算出一个有效的哈希值,只要能通过相应的哈希函数计算出哈希值就可以作为合法的key
常见的可哈希类型有:
- 整数类型
- 浮点数类型
- 字符串类型
- 布尔类型
- 空元组
print(hash(0)) # 0
print(hash(3.14)) # 485696759011932780
print(hash('hello')) # -907417682774578891
print(hash(True)) # 1
print(hash(())) # 3527539
上面浮点数、字符串、空元组计算出的
hash
值可能不同的设备不尽相同
不可计算出哈希值的有:
- 列表
- 字典
print(hash([1, 2, 3])) # TypeError: unhashable type: 'list'
print(hash({1:1})) # TypeError: unhashable type: 'dict'
Python文件操作
打开文件
使用open()
函数打开文件,参数与C语言的fopen()
函数类似,不再赘述,主要打开方式有:
- 读:
'r'
- 写:
'w'
- 追加写:
'a'
如果读取中文文本文件时遇到了下面的报错:
UnicodeDecodeError: 'gbk' codec can't decode byte 0xb0 in position 20: illegal multibyte sequence
表示文件编码和解码不一致,Python默认文件解码方式跟随操作系统,而Windows操作系统默认编码是GBK,如果文件本身编码是UTF-8,需要在open()
函数添加第三个参数设置编码方式为UTF-8:encoding="utf-8"
关闭文件
使用close()
函数关闭文件,没有参数
注意,Python一次运行可以打开文件是有数量限制的,所以用完文件要及时关闭防止出现文件达到上限
读文件
以'r'
方式打开文件后,可以使用read()
方法指定读取字符个数,例如:
当前有一个test.txt
文件,里面有下面的内容:
读取前五个字符:
# 打开文件
f = open('test.txt', 'r', encoding="utf-8")
# 读取文件指定个数字符
print(f.read(5)) # 巴山楚水凄
可以使用for
循环一次读取多行
# 打开文件
f = open('test.txt', 'r', encoding="utf-8")
# 使用for循环读取文件
for i in f:
print(f"line: {i}")
输出结果:
line: 巴山楚水凄凉地
line: 高锰酸钾制氧气
需要注意,文本文件本身每一行就存在一个换行,再加上print()
函数会自动换行,所以产生了空行。如果不想要空行,可以在打印时加上end=""
参数,表示以空字符结尾
可以使用readlines()
函数将文件内容读取出来并放置于一个列表,如果文件中的内容有换行,则会对应行结尾出现\n
print(f.readlines()) # ['巴山楚水凄凉地\n', '高锰酸钾制氧气\n']
上下文管理器
使用C语言时打开文件有时因为文件过多可能导致部分文件忘记关闭,在Python中只使用open()
函数和close()
函数也会存在同样的问题,所以为了解决这个问题,可以使用上下文管理器,该管理器会在文件使用完毕后自动调用关闭函数,但是此时需要使用with
语句打开文件,代码如下:
# 上下文管理器
with open('test.txt', 'r', encoding="utf-8") as f_file:
# 读取文件指定个数字符
print(f_file.read(5)) # 巴山楚水凄