第三章 数据类型
在 Python 中,数据类型是指变量所表示的数据的类型。Python 中常见的数据类型包括:
数字类型:包括整数(int)、浮点数(float)、复数(complex)等。
布尔类型:包括 True 和 False 两个取值。
字符串类型:用于表示文本数据,使用单引号或双引号括起来。
列表类型:用于存储一系列有序的数据,使用方括号括起来。
元组类型:类似于列表,但是元组中的元素不可修改,使用圆括号括起来。
集合类型:用于存储无序的、不重复的数据,使用大括号括起来。
字典类型:用于存储键值对,键和值之间使用冒号分隔,使用大括号括起来。
此外,Python 还支持其他一些数据类型,如 bytes 类型、bytearray 类型、range 类型、frozenset 类型、memoryview 类型等,但这些类型使用相对较少。
Python 是一门动态语言,变量的数据类型可以根据赋值的内容自动推断,不需要显式地声明数据类型。例如,以下代码中的 a 变量是一个整数类型的变量,b 变量是一个字符串类型的变量:
a = 10
b = 'hello'
在 Python 中,可以使用 type() 函数获取变量的数据类型。例如,type(a) 返回 <class 'int'>,表示变量 a 的类型是整数类型。
3.1 Python基础数据类型
Python 中的基础数据类型包括数字类型、布尔类型、字符串类型、列表类型、元组类型、集合类型和字典类型。
数字类型:包括整数(int)、浮点数(float)、复数(complex)等。例如,a = 10 定义了一个整数类型的变量 a,b = 3.14 定义了一个浮点数类型的变量 b,c = 2 + 3j 定义了一个复数类型的变量 c。
布尔类型:包括 True 和 False 两个取值。例如,a = True 定义了一个布尔类型的变量 a,b = False 定义了一个布尔类型的变量 b。
字符串类型:用于表示文本数据,使用单引号或双引号括起来。例如,a = 'hello' 定义了一个字符串类型的变量 a,b = "world" 定义了一个字符串类型的变量 b。
列表类型:用于存储一系列有序的数据,使用方括号括起来。例如,a = [1, 2, 3] 定义了一个列表类型的变量 a,其中包含三个整数类型的元素。
元组类型:类似于列表,但是元组中的元素不可修改,使用圆括号括起来。例如,a = (1, 2, 3) 定义了一个元组类型的变量 a,其中包含三个整数类型的元素。
集合类型:用于存储无序的、不重复的数据,使用大括号括起来。例如,a = {1, 2, 3} 定义了一个集合类型的变量 a,其中包含三个整数类型的元素。
字典类型:用于存储键值对,键和值之间使用冒号分隔,使用大括号括起来。例如,a = {'name': 'Tom', 'age': 20} 定义了一个字典类型的变量 a,其中包含两个键值对,键是字符串类型,值是任意类型。
除了以上基础数据类型,Python 还支持一些其他数据类型,例如 bytes 类型、bytearray 类型、memoryview 类型等。
3.1.1 整型
在 Python 中,整数是一种基本数据类型。Python 的整数类型可以表示任意大小的整数(没有取值范围的限制)。整数类型可以用十进制、二进制、八进制和十六进制表示。
以下是几个例子:
x = 123 # 十进制
y = 0b1111 # 二进制,相当于十进制的 15
z = 0o17 # 八进制,相当于十进制的 15
w = 0x0f # 十六进制,相当于十进制的 15
可以使用 type() 函数来检查变量的类型,如下所示:
x = 123
print(type(x)) # 输出 <class 'int'>
Python 还提供了一些内置的函数用于整数处理,比如:
abs(x):返回 x 的绝对值。
divmod(x, y):返回 x 除以 y 的商和余数。
pow(x, y[, z]):返回 x 的 y 次幂对 z 取模的结果(如果 z 给出,则求余)。
round(x[, n]):将 x 四舍五入到 n 位小数,如果省略 n,则将其舍入到最接近的整数。
hex(x):将 x 转换为十六进制字符串。
bin(x):将 x 转换为二进制字符串。
oct(x):将 x 转换为八进制字符串。
以下是一些示例:
x = -123
print(abs(x)) # 输出 123
x, y = 10, 3
print(divmod(x, y)) # 输出 (3, 1)
x, y, z = 2, 3, 5
print(pow(x, y, z)) # 输出 3
x = 3.14159265359
print(round(x, 3)) # 输出 3.142
x = 255
print(hex(x)) # 输出 0xff
print(bin(x)) # 输出 0b11111111
print(oct(x)) # 输出 0o377
3.1.2 浮点型
在Python中,浮点型是一种表示带有小数点的数字的数据类型。通常使用float关键字来表示浮点数。
以下是一些关于Python浮点数的基本知识点:
浮点数可以包含小数点,也可以使用科学计数法(例如,1.23e6)来表示非常大或非常小的数字。
在Python 3.x中,浮点数默认使用双精度(64位)表示,最大值为1.8 x 10^308,最小值为5.0 x 10^-324。
在Python中,浮点数可以进行基本的算术运算(加减乘除)和比较运算(等于,不等于,大于,小于等)。
以下是一些Python浮点数的示例:
# 定义一个浮点数
x = 3.14
y = 2.0
# 浮点数加法
print(x + y) # 输出 5.14
# 浮点数乘法
print(x * y) # 输出 6.28
# 浮点数比较
print(x > y) # 输出 True
print(x == y) # 输出 False
需要注意的是,由于浮点数的精度限制,可能会出现一些不精确的计算结果。
可以使用"=="比较两个浮点数是否相等,但不应该使用"=="来比较两个浮点数的大小。这是因为由于浮点数在计算机内部的二进制表示方式,可能会导致精度丢失,从而导致一些预期外的结果。
例如,如果使用以下代码比较两个浮点数:
a = 0.1 + 0.2
b = 0.3
if a == b:
print("a equals b")
else:
print("a does not equal b")
则会输出"a does not equal b",因为0.1 + 0.2的结果与0.3并不完全相等。
如果要比较两个浮点数的大小,可以使用"<"和">"等比较运算符,但需要注意潜在的精度问题。
同一个对象。具体来说,"=="比较的是两个变量的值是否相等,而"is"比较的是两个变量的身份标识是否相等(即它们是否引用同一个对象)。
例如,假设有以下代码:
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == b) # True
print(a is b) # False
print(a is c) # True
在这个例子中,变量a和变量b都包含相同的值[1, 2, 3],因此"a == b"的结果为True。但是由于a和b引用的是两个不同的对象,它们的身份标识不同,因此"a is b"的结果为False。另一方面,由于a和c引用的是同一个对象,它们的身份标识相同,因此"a is c"的结果为True。
因此,一般来说,如果你想比较两个变量的值是否相等,应该使用"==",而如果你想比较两个变量是否引用同一个对象,应该使用"is"。
3.1.3 布尔型
在Python中,布尔类型是一种基本数据类型,它只有两个值:True和False。布尔类型通常用于控制流程和逻辑运算,例如条件语句和循环语句。
在Python中,可以通过以下方式创建一个布尔类型的变量:
x = True
y = False
Python中的布尔运算符包括逻辑与(and)、逻辑或(or)和逻辑非(not)。它们的运算规则如下:
逻辑与(and):当所有操作数都为True时,结果为True;否则结果为False。
逻辑或(or):当任意一个操作数为True时,结果为True;否则结果为False。
逻辑非(not):对操作数进行取反,如果操作数为True,则结果为False;如果操作数为False,则结果为True。
例如:
x = True
y = False
z = x and y # False
w = x or y # True
v = not x # False
需要注意的是,Python中的布尔类型实际上是整型的子类型,其中True被定义为整数1,而False被定义为整数0。因此,在进行数值运算时,True和False可以被当作整数使用,例如:
x = True
y = False
z = x + y # z的值为1
在 Python 中,字符串是按照 ASCII 编码的顺序进行比较的,而不是按照字母表的顺序。ASCII 编码是一种将字符映射到数字的标准,例如 A 对应 65,B 对应 66,a 对应 97,b 对应 98 等等。因此,如果要比较两个字符串,就要逐个比较它们对应的 ASCII 编码值。例如,“apple” < “banana” 是 True,因为 a 的 ASCII 编码值小于 b 的;“Apple” < “apple” 也是 True,因为 A 的 ASCII 编码值小于 a 的。
ord 函数是 Python 的一个内置函数,它可以返回一个字符的 Unicode 编码值。Unicode 编码是一种将字符映射到数字的标准,它可以支持多种语言和符号。ord 函数的语法是 ord(x),其中 x 是一个长度为 1 的字符串。例如,ord("A") 返回 65,ord("中") 返回 20013。
将多个简单的布尔表达式用逻辑运算符连接起来可以组成复杂的布尔表达式。
and运算符:当两个表达式都为True时返回True,否则返回False。
or运算符:当两个表达式至少有一个为True时返回True,否则返回False。
not运算符:将一个表达式的逻辑值取反,如果表达式为True则返回False,如果表达式为False则返回True。
例如:
x = 5
y = 10
z = 15
# and运算符
if x < y and y < z:
print("Both conditions are True")
# or运算符
if x < y or x > z:
print("At least one condition is True")
# not运算符
if not(x == y):
print("x is not equal to y")
输出:
Both conditions are True
At least one condition is True
x is not equal to y
复杂的布尔表达式的值可以根据以下规则来确定:
从左到右依次计算表达式中的每个子表达式。
对于and运算符,如果一个子表达式的值为False,则整个表达式的值为False,不再计算后面的子表达式。如果所有子表达式的值都为True,则整个表达式的值为True。
对于or运算符,如果一个子表达式的值为True,则整个表达式的值为True,不再计算后面的子表达式。如果所有子表达式的值都为False,则整个表达式的值为False。
对于not运算符,如果子表达式的值为True,则整个表达式的值为False,反之则为True。
例如:
x = 5
y = 10
z = 15
result = (x < y) and (y < z) or (x == z)
print(result) # True
这里的复杂表达式可以拆分为两部分,(x < y) and (y < z) 和 (x == z),分别计算其值为True和False,然后将其用or运算符连接,得到最终结果为True。
Python 中的元素都有自己的布尔值。在 Python 中,我们可以通过bool函数来查看一个元素的布尔值,如果元素的布尔值为True,则表示元素是真实存在的;如果元素的布尔值为False,则表示元素不存在或为假值。例如:
bool(1) # True
bool(0) # False
bool("hello") # True
bool("") # False
bool([]) # False
bool([1, 2, 3]) # True
bool(None) # False
在上面的例子中,整数1的布尔值为True,整数0的布尔值为False;字符串"hello"的布尔值为True,空字符串""的布尔值为False;空列表[]的布尔值为False,有元素的列表[1, 2, 3]的布尔值为True;None的布尔值为False。
3.1.4 复数
在 Python 中,可以使用复数(complex)来表示实部和虚部组成的数值。复数的表示形式为“a+bj”,其中a为实部,b为虚部,j为虚数单位。
Python 中可以通过使用“complex(real, imag)”来创建一个复数,其中real为实部,imag为虚部。实部和虚部都可以是整数或浮点数。例如:
x = complex(3, 4)
print(x)
输出:
(3+4j)
可以通过“x.real”和“x.imag”分别访问x的实部和虚部。例如:
print(x.real) # 输出 3.0
print(x.imag) # 输出 4.0
复数支持基本的运算操作,如加、减、乘和除,也可以使用内置函数如abs、pow、round等函数。
3.2 字符串
字符串是 Python 中的一种基本数据类型,用于表示文本类型的数据。字符串是一连串的字符,可以使用单引号、双引号或三引号表示。例如:
str1 = 'hello'
str2 = "world"
str3 = '''hello world'''
3.2.1 字符串的创建
创建字符串有多种方式,包括:
使用单引号或双引号将字符括起来,例如:
string1 = 'hello'
string2 = "world"
使用三重引号来创建多行字符串,例如:
string3 = '''This is a
multi-line string.'''
使用字符串的构造函数 str() 来创建字符串,例如:
string4 = str(123)
注意,字符串是不可变的,一旦创建,就无法修改其内容。
三引号(单、双三引号)允许字符跨越多行,并在输出时保持原来的格式,字符串中可以包含换行符、
制表符、引号等特殊字符,方便编写多行文本、长字符串等场合。下面是一些使用三引号创建多行字符串的示例:
使用单引号三引号:
str1 = '''这是一个
多行
字符串'''
使用双引号三引号:
str2 = """这是一个
多行
字符串"""
三引号中的字符串可以包含单引号和双引号,无需进行转义:
str3 = '''I said, "I don't know."'''
str4 = """He said, 'Yes, I will.'"""
当然,如果需要在字符串中使用三引号,则可以在字符串中使用转义符号(\):
str5 = """This is a triple-quote: \"\"\""""
如果我们需要在字符串中使用反斜杠字符,但不希望反斜杠被视为特殊字符,我们可以在字符串前面添加一个 r 或 R 前缀,这将使字符串成为原始字符串,例如:
path = r"C:\Users\username\Documents"
print(path)
输出:
C:\Users\username\Documents
3.2.2 常用的字符串方法
string[index]
字符串确实是序列类型,每个字符在字符串中都有一个对应的索引位置。字符串中的第一个字符的索引为0,最后一个字符的索引为字符串长度减一。
我们可以通过字符串的索引来获取其中的字符,用法为string[index],其中string是要操作的字符串,index是要获取的字符的位置,也就是索引。
例如,如果我们有一个字符串"hello",我们可以使用索引来获取其中的字符:
string = "hello"
print(string[0]) # 输出: h
print(string[1]) # 输出: e
print(string[2]) # 输出: l
print(string[3]) # 输出: l
print(string[4]) # 输出: o
需要注意的是,如果我们使用一个超出索引范围的索引来访问字符串,Python将会抛出IndexError异常。
str[startindex:endindex:step]
str[startindex:endindex:step] 表达式可以用于对字符串进行切片(分片)操作,其中:
startindex 表示起始索引位置(包含在切片中),默认为 0。
endindex 表示结束索引位置(不包含在切片中),默认为字符串的长度。
step 表示切片的步长,默认为 1。
下面是一些示例:
s = 'abcdefg'
# 获取前三个字符
print(s[:3]) # 'abc'
# 获取后三个字符
print(s[-3:]) # 'efg'
# 获取偶数索引位置上的字符
print(s[::2]) # 'aceg'
# 获取奇数索引位置上的字符
print(s[1::2]) # 'bdf'
# 反转字符串
print(s[::-1]) # 'gfedcba'
len()
len()函数为 Python 内置函数,用来返回对象(字符串、列表、元组)的长度或项目个数(字典 )。
len()函数是Python内置函数,可以返回字符串、列表、元组等对象的长度或项目个数。它可以用于任何可迭代对象。例如,可以使用len()函数查找字符串中字符的数量,也可以使用它来确定列表或元组中项的数量。甚至可以使用它来确定字典中键值对的数量。
id()
在Python中,id()函数用于返回对象的唯一标识符,即对象在内存中的地址。每个对象在创建时都会被分配一个唯一的标识符,这个标识符在对象的整个生命周期中都不会改变。
下面是一个简单的例子:
a = 10
print(id(a)) # 输出对象a的唯一标识符
输出结果可能会因为Python解释器的实现而有所不同,但都应该是一串十六进制数字,表示对象在内存中的地址。
字符串复制
在 Python 中,可以使用乘法操作符(*)将一个字符串复制多次。例如,要将字符串 "Hello" 复制 3 次,可以使用以下代码:
s = "Hello" * 3
print(s)
这将输出 "HelloHelloHello"。
字符串合并
在 Python 中,可以使用加号 + 来连接字符串,也可以使用乘号 * 来重复字符串。
例如:
str1 = 'Hello'
str2 = 'World'
str3 = str1 + str2
print(str3) # 输出:HelloWorld
str4 = str1 * 3
print(str4) # 输出:HelloHelloHello
注意,加号 + 只能连接字符串,不能连接字符串和数字等其他类型的数据。如果要连接其他类型的数据,需要先将其转换为字符串类型。
成员测试in、not in
成员测试指的是判断一个元素是否属于某个序列(如字符串、列表、元组等)。
Python 中使用关键字 in 来进行成员测试,如果该元素属于该序列,则返回 True,否则返回 False。
例如:
my_list = [1, 2, 3, 4, 5]
print(3 in my_list) # True
print(6 in my_list) # False
可以看到,3 属于 my_list 序列,所以第一个成员测试返回 True;而 6 不属于 my_list 序列,所以第二个成员测试返回 False。
另外,还可以使用关键字 not in 进行成员测试,该操作符的作用是判断某个元素是否不属于某个序列。例如:
my_str = "Hello, world!"
print("world" in my_str) # True
print("Python" not in my_str) # True
字符串格式化运算符:%s
在 Python 中,我们可以使用字符串格式化运算符 % 来将不同类型的数据格式化成一个字符串。这种方法可以让我们更加灵活地控制字符串的输出格式。
字符串格式化运算符 % 需要两个参数:一个是要格式化的字符串,一个是要插入的数据。格式化字符串中用 % 作为占位符,表示要插入数据的位置,然后在运算符后面加上一个字母来表示要插入的数据的类型。
以下是一些常用的格式化字符:
%s:表示要插入一个字符串
%d:表示要插入一个整数
%f:表示要插入一个浮点数
下面是一些示例:
name = "Alice"
age = 25
print("My name is %s and I am %d years old." % (name, age))
score = 89.5
print("My score is %.2f." % score)
这段代码会输出:
My name is Alice and I am 25 years old.
My score is 89.50.
其中,%s 会被字符串 name 替换,%d 会被整数 age 替换,%.2f 会被浮点数 score 替换,并且保留两位小数。我们可以根据自己的需要调整格式化字符串和插入数据的类型。
格式定义符除了可以控制输出格式外,还可以进行进一步的控制,如设置宽度、精度、左右对齐等。常用的格式定义符控制语法如下:
%s: 字符串(默认右对齐)
%d: 十进制整数(默认右对齐)
%f: 浮点数(默认右对齐)
%e: 科学计数法(默认右对齐)
%x: 十六进制整数(默认右对齐)
%o: 八进制整数(默认右对齐)
%c: 单个字符(默认右对齐)
格式定义符后可以添加修饰符来控制输出格式:
%nd: 控制输出宽度,n为输出宽度,若宽度不足则用空格填充。
%-nd: 左对齐输出,n为输出宽度,若宽度不足则用空格填充。
%0nd: 输出宽度,n为输出宽度,若宽度不足则用0填充。
%m.nf: 控制输出精度,m为整个数值的宽度,n为小数部分的宽度,f为浮点数的格式。
其他常用方法
str.center(width,fillchar)
str.center(width,fillchar) 方法返回一个长度为 width 的新字符串,将原字符串居中,并用 fillchar 填充两侧空白部分。
其中,可选参数 fillchar 表示用于填充空白部分的字符,如果不指定,默认为空格。
示例:
str = "Hello"
print(str.center(10)) # 输出: Hello
print(str.center(10, '-')) # 输出:--Hello---
解释:
第一行代码将字符串 Hello 居中,由于字符串长度为 5,而 width 为 10,因此在两侧填充了 5 个空格。
第二行代码将字符串 Hello 居中,由于 fillchar 指定为 -,因此在两侧填充了 2 个 -。
2. str.count(sub, start, end)
str.count(sub, start, end) 方法用于统计子字符串 sub 在 str 中出现的次数,其中:
sub:要搜索的子字符串。
start:字符串开始搜索的位置,默认为第一个字符,索引值为0。
end:字符串结束搜索的位置,默认为字符串的长度,即搜索到最后一个字符。
下面是一个例子:
str = "hello world"
count = str.count('l')
print(count) # 输出 3
count = str.count('l', 4)
print(count) # 输出 2
count = str.count('l', 4, 8)
print(count) # 输出 1
在上面的例子中,第一个 count 的值为 3,因为字符串 "hello world" 中字符 'l' 出现了 3 次。第二个 count 的值为 2,因为从索引位置 4 开始到字符串末尾,字符 'l' 出现了 2 次。第三个 count 的值为 1,因为从索引位置 4 开始到索引位置 8 结束的子字符串 "o wo" 中只包含一个字符 'l'。
3. str.startswith(obj, start, end)
str.startswith(obj, start, end) 方法用于检查字符串是否以给定的对象开头。
其中,参数obj表示要检查的对象,可以是字符串、元组或列表;start表示检查的起始位置,默认为0,即从字符串开头开始检查;end表示检查的结束位置,默认为字符串的长度。
如果字符串以给定的对象开头,则返回True,否则返回False。
示例代码:
str1 = "Hello, world!"
print(str1.startswith("Hello")) # 输出 True
print(str1.startswith("ello", 1)) # 输出 True
print(str1.startswith("World", 7, 12)) # 输出 False
4. index(obj,start,end)
str.index(obj, start, end) 方法在字符串中查找指定的子字符串,并返回第一次出现的索引值。如果没有找到指定的子字符串,则会抛出 ValueError 异常。
参数说明:
obj: 必需,指定要查找的子字符串。
start: 可选,查找的起始位置,默认为 0。
end: 可选,查找的结束位置,默认为字符串的长度。
示例代码:
str1 = 'hello, world!'
print(str1.index('o')) # 输出 4
print(str1.index('o', 5)) # 输出 7,从索引 5 开始查找
print(str1.index('o', 5, 8)) # 抛出 ValueError 异常,因为 'o' 不在索引 5~8 的范围内
输出结果:
4
7
ValueError: substring not found
5. join(sequence)
join() 是一个字符串方法,用于将一个序列中的元素连接起来,形成一个新的字符串。
语法如下:
new_string = separator.join(sequence)
其中,separator 是分隔符,可以是任何字符串。sequence 是需要连接的序列,通常是一个列表、元组或字符串。
示例:
>>> words = ['Hello', 'world', 'this', 'is', 'Python']
>>> separator = ' '
>>> new_string = separator.join(words)
>>> print(new_string)
Hello world this is Python
在上面的示例中,将一个列表 words 中的元素以空格为分隔符连接成一个新的字符串。
6. str.strip(sub)
str.strip(sub) 方法返回一个去掉字符串两端(不包括内部)的所有 sub 的字符串副本。如果 sub 被省略或为 None,则将删除所有空白符(包括换行符、制表符和空格)。
例如,假设有一个字符串 s = " hello world ",则 s.strip() 将返回 "hello world",因为前导和尾随空格已被删除。如果给定参数 "o", 则 s.strip("o") 将返回 " hello world ",因为该方法只删除首尾的 "o"。
示例代码:
s = " hello world "
print(s.strip()) # 输出: "hello world"
s = "boo bar baz"
print(s.strip("b")) # 输出: "oo bar baz"
7. str.replace(old,new,[max])
str.replace() 方法用于将字符串中指定的子字符串替换为新的子字符串,并返回替换后的新字符串。其语法格式为:
str.replace(old, new[, max])
其中,old 参数是要被替换的旧字符串,new 参数是要替换成的新字符串。如果指定了 max 参数,则只替换前 max 个出现的旧字符串。如果不指定 max 参数,则所有的旧字符串都将被替换。
示例:
str1 = "Hello, World! Hello, Python!"
str2 = str1.replace("Hello", "Hi")
print(str2) # 输出:"Hi, World! Hi, Python!"
str3 = str1.replace("Hello", "Hi", 1)
print(str3) # 输出:"Hi, World! Hello, Python!"
注意,str.replace() 方法返回的是一个新字符串,而不是在原字符串上进行替换。如果要在原字符串上进行替换,需要将返回的新字符串赋值给原字符串。
8. str.upper()
str.upper()是一个字符串方法,用于将字符串中的所有字母转换为大写字母。
例如:
s = "hello world"
print(s.upper()) # 输出:HELLO WORLD
upper()方法不会改变原始字符串的值,而是返回一个新的字符串,该字符串中的所有字母都是大写字母。
9. str.split(str='',num)
str.split(str='',num) 方法用于通过指定分隔符对字符串进行分割,并返回分割后的字符串列表。
其中,str 为分隔符,默认为空格。num 为分割次数,即最多分割出多少个子字符串。
具体来说,str.split() 表示使用空格为分隔符进行分割;str.split(str) 表示使用 str 为分隔符进行分割;str.split(str, num) 表示使用 str 为分隔符进行最多 num 次分割。
示例如下:
s = "hello world"
lst1 = s.split()
print(lst1) # ['hello', 'world']
lst2 = s.split('o')
print(lst2) # ['hell', ' w', 'rld']
lst3 = s.split('o', 1)
print(lst3) # ['hell', ' world']
字符串的常用操作符:
操作符 | 描述 |
+ | 字符串连接,将两个字符串连接成一个字符串 |
* | 重复输出字符串,返回由字符串重复若干次后的结果 |
[] | 通过索引获取字符串中的字符 |
[:] | 截取字符串中的一部分 |
in | 判断一个字符是否在字符串中 |
not in | 判断一个字符是否不在字符串中 |
r/R | 原始字符串,不会把反斜杠转义成别的字符,常用于正则表达式等 |
% | 格式字符串 |
常用的字符串方法:
方法 | 描述 |
capitalize() | 将字符串第一个字符转换为大写 |
casefold() | 将字符串转换为小写字母,并删除所有大小写标识 |
center(width, fillchar) | 返回一个指定宽度的居中字符串,并使用指定的填充字符进行填充 |
count(sub[, start[, end]]) | 返回子字符串在字符串中出现的次数 |
encode([encoding[, errors]]) | 将字符串编码为指定的编码格式 |
endswith(suffix[, start[, end]]) | 判断字符串是否以指定的后缀结尾 |
expandtabs([tabsize]) | 将字符串中的制表符替换为空格,制表符宽度默认为 8 |
find(sub[, start[, end]]) | 返回子字符串在字符串中首次出现的位置,未找到返回 -1 |
index(sub[, start[, end]]) | 返回子字符串在字符串中首次出现的位置,未找到抛出 ValueError 异常 |
isalnum() | 如果字符串中的所有字符都是字母或数字,则返回 True,否则返回 False |
isalpha() | 如果字符串中的所有字符都是字母,则返回 True,否则返回 False |
isdecimal() | 如果字符串中的所有字符都是十进制数字,则返回 True,否则返回 False |
isdigit() | 如果字符串中的所有字符都是数字,则返回 True,否则返回 False |
islower() | 如果字符串中的所有字母都是小写字母,则返回 True,否则返回 False |
isnumeric() | 如果字符串中的所有字符都是数字,则返回 True,否则返回 False |
isspace() | 如果字符串中只包含空格,则返回 True,否则返回 False |
istitle() | 如果字符串是标题化的(每个单词的首字母都是大写),则返回 True,否则返回 False |
isupper() | 如果字符串中的所有字母都是大写字母,则返回 True,否则返回 False |
join(iterable) | 将可迭代对象的元素用指定的分隔符连接为一个字符串 |
ljust(width[, fillchar]) | 返回一个指定宽度的左对齐字符串,并使用指定的填充字符进行填充 |
lower() | 将字符串中的所有大写字母转换为小写字母 |
lstrip([chars]) | 返回移除左侧指定字符后的字符串,如果未指定字符,默认移除空格 |
partition(sep) | 根据分隔符将字符串分成三部分,返回一个元组,包含分隔符和两个部分 |
replace(old, new[, count]) | 返回将旧字符串替换为新字符串后的新字符串 |
rfind(sub[, start[, end]]) | 返回子字符串在字符串中最后一次出现的位置,未找到返回 -1 |
rindex(sub[, start[, end]]) | 返回子字符串在字符串中最后一次出现的位置,未找到 |
max和min方法不仅适用于数字类型,也适用于字符串类型。对于字符串类型,这两个方法会返回按字典序排列后的最大或最小字符串。具体来说:
max方法返回按字典序排列后的最大字符串,即在该字符串类型的所有字符串中,按照字典序排列后最后一个字符串;
min方法返回按字典序排列后的最小字符串,即在该字符串类型的所有字符串中,按照字典序排列后第一个字符串。
下面是一个示例:
>>> s = 'abcde'
>>> max(s)
'e'
>>> min(s)
'a'
需要注意的是,对于中文字符来说,其字典序并不是按照其在 UTF-8 编码中的顺序排列的,而是按照其在汉字拼音中的顺序排列的。因此,在处理中文字符串时,max和min方法并不能得到正确的结果,需要使用其他方法进行处理。
3.2.3 字符串类型与类型的转换
字符串类型与其他类型的转换:
str() 函数可以将其他数据类型转换为字符串类型。
int() 函数可以将字符串类型转换为整型,但字符串必须是表示整数的形式。
float() 函数可以将字符串类型转换为浮点型,但字符串必须是表示浮点数的形式。
示例代码如下:
# 将整型转换为字符串类型
num1 = 100
str1 = str(num1)
print(str1)
# 将浮点型转换为字符串类型
num2 = 3.14
str2 = str(num2)
print(str2)
# 将字符串类型转换为整型
str3 = '100'
num3 = int(str3)
print(num3)
# 将字符串类型转换为浮点型
str4 = '3.14'
num4 = float(str4)
print(num4)
输出结果如下:
100
3.14
100
3.14
需要注意的是,当字符串无法被转换为对应的数据类型时,会抛出异常。例如,当字符串中含有非数字字符时,将字符串转换为整型或浮点型时会抛出 ValueError 异常。
3.2.4 help函数
help 函数是 Python 内置函数之一,用于获取帮助信息。通过 help 函数可以获取任何 Python 对象的帮助信息,包括函数、类、模块、方法等。
使用方法:在交互式 Python 解释器中,输入 help(对象),其中 对象 可以是任何 Python 对象,例如 help(print) 会显示 print 函数的帮助信息。
另外,在使用 IDE(如 PyCharm)时,也可以在代码中选中某个对象,然后按下 Ctrl + Q(或者鼠标悬停在对象上),就可以显示该对象的帮助信息。
3.3 容易走火入魔的字符编码
3.3.1 字符编码的发展
编码是计算机科学中一个非常重要的概念,它是将字符集中的字符编成指定的编码形式,使得计算机可以读懂和存储这些字符。随着计算机技术的发展,编码也经历了不同的阶段和变迁。
最早的计算机只支持ASCII码,它只包含了128个字符,包括英文字母、数字、标点符号和一些控制字符。由于ASCII码只能表示很有限的字符集,因此人们开始尝试扩展字符集。
于是,不同的国家和地区制定了各自的字符编码标准,如中文常用的GB2312编码和Big5编码,日语常用的Shift-JIS编码等等。这样,随着国际交流和计算机普及,不同的字符编码标准就开始互相冲突和不兼容了。
为了解决字符编码的混乱问题,国际标准化组织ISO于1986年制定了国际标准字符集ISO 8859,其中ISO 8859-1采用了8位编码,包含了西欧大多数语言的字符集,也称为Latin-1。
但是,ISO 8859仍然无法满足全球化的需求,Unicode编码的出现填补了ISO编码的不足。Unicode采用两个字节表示一个字符,它的字符集包含了世界上所有的符号,可以表示几乎所有语言的字符,包括东亚语言和印度语系等。
由于Unicode编码需要两个字节来表示一个字符,因此在存储和传输时会浪费大量的存储空间和带宽。为了解决这个问题,出现了UTF-8编码,它是Unicode的一种变长编码形式,可以根据字符的不同使用1~4个字节进行编码。UTF-8编码保证了与Unicode编码的兼容性,同时又提高了存储和传输效率。
目前,UTF-8已经成为了互联网上使用最广泛的字符编码形式,几乎所有的网页、邮件、聊天工具等都采用了UTF-8编码。
目前,内存中的编码固定为Unicode 编码,这是因为Unicode编码能够表示世界上所有的字符,所以在计算机内存中,所有的字符都以Unicode编码的形式存在。当我们从硬盘上读取数据时,需要根据具体的编码格式将数据解码为Unicode编码,这样才能在内存中正确地表示这些字符。在内存中对字符串进行操作时,也是以Unicode编码的形式进行的。当需要将数据写入硬盘时,需要将Unicode编码转换为具体的编码格式,比如UTF-8或者GBK,然后将其写入到硬盘上的文件中。
3.3.2 字符编码之Python
由于 Python 2 中默认采用的 ASCII 编码不能表示中文等非 ASCII 字符,因此出现了许多不同的解决方案,如使用 u'' 前缀表示 Unicode 字符串、使用 .decode() 和 .encode() 方法进行编码转换等。
Python 3 中默认采用的是 UTF-8 编码,可以直接使用 Unicode 字符串,无需进行额外的编码转换。同时,Python 3 还提供了更加便捷的字符串格式化方式,如 f-string 和 format() 方法。
在 Python 2 中,默认的字符编码格式是 ASCII,而不是 Unicode。在 Python 2 中,Unicode 类型使用 u"string" 表示,而默认字节类型使用 "string" 表示,即没有前缀 u。
这在处理非 ASCII 字符时会导致问题,因为默认编码不能表示非 ASCII 字符。因此,在 Python 2 中,需要使用特殊的编码方式来表示非 ASCII 字符,例如使用 UTF-8 编码的字符串需要使用 "string".decode("utf-8") 来解码为 Unicode 类型。
在 Python 3 中,默认的字符编码格式是 Unicode,也就是说字符串类型 str 存储的是 Unicode 编码字符,而默认的字节类型是 bytes,用于存储二进制数据或者在网络传输中传递数据。在 Python 3 中,我们可以通过 b 前缀将字符串类型转换为 bytes 类型,也可以通过在字符串类型前加上 u 前缀来显式地声明字符串类型为 Unicode 编码。此外,Python 3 也支持在文件头中声明文件的编码格式。
Python 2、Python 3可以通过 sys 模块来获取 Python 解释器的默认编码和默认字节类型。
在 Python 2 中,可以通过以下代码来获取默认编码和默认字节类型:
import sys
print(sys.getdefaultencoding()) # 获取默认编码
print(type('hello')) # 获取默认字节类型
在 Python 3 中,可以通过以下代码来获取默认编码和默认字节类型:
import sys
print(sys.getdefaultencoding()) # 获取默认编码
print(type(b'hello')) # 获取默认字节类型
需要注意的是,在 Python 3 中,字符串默认为 Unicode 编码,因此获取字符串的类型需要使用 Unicode 字符串,而不是字节字符串。
3.4 列表
列表(List)是Python中常用的一种数据结构,它可以容纳任意数量的Python对象,包括其他列表。列表使用方括号[]定义,其中每个元素使用逗号分隔。列表是一种有序的集合,可以通过索引访问其中的元素。
例如,创建一个包含一些整数和字符串的列表:
my_list = [1, 2, 3, 'hello', 'world']
可以通过索引访问列表中的元素:
print(my_list[0]) # 输出1
print(my_list[3]) # 输出'hello'
使用insert()方法在指定位置插入元素:
my_list.insert(0, 'start')
print(my_list) # 输出['start', 1, 2, 3, 'hello', 'world', 'Python']
使用remove()方法删除指定元素:
my_list.remove('hello')
print(my_list) # 输出['start', 1, 2, 3, 'world', 'Python']
使用pop()方法弹出指定位置的元素:
my_list.pop(2)
print(my_list) # 输出['start', 1, 3, 'world', 'Python']
列表也支持切片操作,可以通过切片获取列表的子集:
print(my_list[1:4]) # 输出[1, 3, 'world']
还可以使用len()方法获取列表的长度:
print(len(my_list)) # 输出5
需要注意的是,列表是可变的对象,因此可以在原地修改。列表中的元素可以是不同类型的对象,也可以包含其他列表。
除了列表之外,Python还提供了其他几种常用的序列类型,包括元组(Tuple)、字符串(String)和范围(Range)。
3.4.1 列表的基本操作
1.创建列表
在 Python 中,可以使用方括号 [ ] 或者 list() 函数来创建列表。
使用方括号可以直接创建一个包含指定元素的列表,例如:
my_list = [1, 2, 3, 4, 5]
使用 list() 函数可以将一个可迭代对象(如字符串、元组、集合等)转换为列表,例如:
my_string = "Hello, World!"
my_list = list(my_string)
以上代码将字符串 "Hello, World!" 转换为列表,结果为 ['H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!']。
除此之外,还可以使用列表推导式来创建列表。例如,以下代码可以创建一个包含 1 到 10 中所有偶数的列表:
my_list = [i for i in range(1, 11) if i % 2 == 0]
以上代码将变量 i 从 1 到 10 遍历一遍,如果 i 是偶数则添加到列表中,最终结果为 [2, 4, 6, 8, 10]。
2. 列表的合并
在 Python 中,可以通过 + 运算符来合并两个列表。例如:
list1 = [1, 2, 3]
list2 = [4, 5, 6]
list3 = list1 + list2
print(list3)
输出结果为:
[1, 2, 3, 4, 5, 6]
另外,也可以使用 extend() 方法将一个列表中的元素添加到另一个列表中。例如:
list1 = [1, 2, 3]
list2 = [4, 5, 6]
list1.extend(list2)
print(list1)
输出结果也为:
[1, 2, 3, 4, 5, 6]
3. 列表的重复
可以使用乘法操作符 * 对列表进行重复操作,例如:
list1 = [1, 2, 3]
list2 = list1 * 3
print(list2) # [1, 2, 3, 1, 2, 3, 1, 2, 3]
这里的 list2 就是 list1 重复了 3 次。
4. 成员资格
成员资格指的是检查某个元素是否属于一个列表。在 Python 中,可以使用 in 和 not in 运算符来进行成员资格检查。其基本语法格式如下:
# in运算符
if element in my_list:
# 满足条件的操作
# not in运算符
if element not in my_list:
# 满足条件的操作
其中,element 是待检查的元素,my_list 是待检查的列表。如果 element 在 my_list 中出现,则 element in my_list 的值为 True,否则为 False;如果 element 不在 my_list 中出现,则 element not in my_list 的值为 True,否则为 False。
5. 通过索引取值
在 Python 中,可以通过索引来获取列表中的元素。Python 中的索引从 0 开始,也就是说,列表的第一个元素的索引为 0,第二个元素的索引为 1,以此类推。
以下是获取列表元素的示例代码:
fruits = ['apple', 'banana', 'orange']
print(fruits[0]) # 输出:apple
print(fruits[1]) # 输出:banana
print(fruits[2]) # 输出:orange
可以使用负数索引来获取列表中的倒数第几个元素。例如,索引 -1 表示列表中的最后一个元素,索引 -2 表示列表中的倒数第二个元素,以此类推。以下是一个示例代码:
fruits = ['apple', 'banana', 'orange']
print(fruits[-1]) # 输出:orange
print(fruits[-2]) # 输出:banana
print(fruits[-3]) # 输出:apple
6. 列表切片操作
列表切片操作指的是获取列表中部分元素的操作,语法为 list[start:end:step],其中:
start:切片的起始位置,默认为 0。
end:切片的结束位置,默认为列表的长度。
step:切片的步长,默认为 1。
举个例子,假设有一个列表 lst = [1, 2, 3, 4, 5],那么:
lst[1:3] 表示获取从第 1 个元素到第 2 个元素(不包括第 3 个元素)组成的列表,即 [2, 3]。
lst[:3] 表示获取从第 0 个元素到第 2 个元素(不包括第 3 个元素)组成的列表,即 [1, 2, 3]。
lst[::2] 表示获取从第 0 个元素到最后一个元素,步长为 2 的元素组成的列表,即 [1, 3, 5]。
需要注意的是,切片操作会返回一个新的列表,不会改变原有列表的值。
fruits = ['apple', 'banana', 'orange', 'peach', 'pear']
print(fruits[1:3]) # 输出:['banana', 'orange']
print(fruits[:2]) # 输出:['apple', 'banana']
print(fruits[2:]) # 输出:['orange', 'peach', 'pear']
7. 通过for循环取值
通过 for 循环遍历列表元素可以取得列表中所有的值,示例如下:
my_list = [1, 2, 3, 4, 5]
for item in my_list:
print(item)
输出结果:
1
2
3
4
5
在 for 循环中,每次迭代时,变量 item 会被赋值为列表中的一个元素。因此,通过循环可以依次访问列表中的所有元素。
8. 为列表添加元素
为列表添加元素有以下几种方式:
使用 append() 方法向列表尾部添加一个元素。
my_list = [1, 2, 3]
my_list.append(4)
print(my_list) # [1, 2, 3, 4]
使用 insert() 方法向列表的指定位置添加一个元素。
my_list = [1, 2, 3]
my_list.insert(1, 4)
print(my_list) # [1, 4, 2, 3]
使用加号 + 运算符合并两个列表。
my_list = [1, 2, 3]
my_list += [4]
print(my_list) # [1, 2, 3, 4]
使用 extend() 方法将一个列表中的元素添加到另一个列表的尾部。
my_list = [1, 2, 3]
my_list.extend([4, 5])
print(my_list) # [1, 2, 3, 4, 5]
需要注意的是,使用 append() 和 extend() 方法添加元素是修改原列表,而不是创建一个新列表。而使用加号 + 运算符和 insert() 方法则会创建一个新的列表对象。
9. 列表元素更新
列表中的元素可以通过索引进行更新,具体操作如下:
# 定义一个列表
lst = [1, 2, 3, 4, 5]
# 将第二个元素更新为 10
lst[1] = 10
# 输出更新后的列表
print(lst) # [1, 10, 3, 4, 5]
在上述代码中,通过索引 1 访问列表 lst 中的第二个元素,并将其更新为 10。更新后,打印列表 lst 可以看到第二个元素的值已经变为 10。
需要注意的是,如果通过索引更新列表中不存在的元素,会抛出 IndexError 异常,例如:
# 定义一个列表
lst = [1, 2, 3, 4, 5]
# 尝试将第六个元素更新为 10,会抛出 IndexError 异常
lst[5] = 10
在上述代码中,由于列表 lst 只有五个元素,而尝试将第六个元素更新为 10,会抛出 IndexError 异常。
10. 通过下标索引删除元素
可以使用 del 关键字和元素下标来删除列表中的元素,例如:
my_list = ['apple', 'banana', 'orange', 'pear']
del my_list[2]
print(my_list) # ['apple', 'banana', 'pear']
这样就可以删除列表中下标为 2 的元素,即 'orange'。
3.4.2 列表的常用方法
列表是 Python 中最常用的数据类型之一,提供了许多有用的方法来操作和处理数据。以下是一些常用的列表方法:
append(x):在列表末尾添加元素 x。
extend(iterable):将可迭代对象中的元素添加到列表末尾。
insert(i, x):在指定的索引位置 i 插入元素 x。
remove(x):从列表中删除第一个值为 x 的元素。
pop([i]):移除并返回指定索引位置 i 的元素,如果没有指定索引,则移除并返回列表的最后一个元素。
index(x):返回列表中第一个值为 x 的元素的索引,如果 x 不在列表中会报错。
count(x):返回列表中值为 x 的元素的个数。
sort(key=None, reverse=False):对列表进行排序,默认按照元素的大小进行升序排序,可以通过 key 参数指定自定义排序函数,reverse 参数指定是否按照降序排序。
reverse():反转列表中的元素顺序。
clear():移除列表中的所有元素。
这些方法可以通过列表对象的方法调用来使用,例如 my_list.append(x) 将元素 x 添加到 my_list 列表的末尾。
操作符 | 描述 | 示例 |
+ | 连接两个列表 | [1, 2, 3] + [4, 5, 6] 结果为 [1, 2, 3, 4, 5, 6] |
* | 重复列表 | [1, 2, 3] * 2 结果为 [1, 2, 3, 1, 2, 3] |
in | 判断元素是否在列表中 | 2 in [1, 2, 3] 结果为 True |
not in | 判断元素是否不在列表中 | 4 not in [1, 2, 3] 结果为 True |
== | 判断两个列表是否相等 | [1, 2, 3] == [1, 2, 3] 结果为 True |
!= | 判断两个列表是否不相等 | [1, 2, 3] != [4, 5, 6] 结果为 True |
注意:上述操作符的示例都是针对 Python 中的列表对象的,对于其他序列类型,如字符串、元组等,这些操作符的含义也类似。
列表常用方法和内置函数:
方法 | 描述 |
append() | 在列表末尾添加新元素 |
extend() | 在列表末尾一次性追加另一个序列中的多个值(可迭代对象) |
insert() | 在指定位置插入一个元素 |
remove() | 删除列表中某个值的第一个匹配项 |
pop() | 移除列表中的一个元素(默认最后一个元素),并返回该元素的值 |
clear() | 清空列表中的所有元素 |
index() | 返回列表中第一个值为指定值的元素的索引 |
count() | 返回指定元素在列表中出现的次数 |
sort() | 对列表进行排序 |
reverse() | 将列表中的元素倒序排列 |
copy() | 返回列表的一个浅拷贝 |
内置函数 | 描述 |
len() | 返回列表中元素的个数 |
max() | 返回列表中元素的最大值 |
min() | 返回列表中元素的最小值 |
sum() | 返回列表中元素的总和 |
sorted() | 返回一个排序后的列表(不改变原列表) |
list() | 将一个可迭代对象转换为列表 |
3.4.3 列表的嵌套
列表嵌套是指在一个列表中嵌套另一个列表。在Python中,一个列表的元素可以是任意类型的对象,包括另一个列表。
下面是一个简单的例子,展示了一个列表嵌套另一个列表的形式:
nested_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
这个嵌套列表由三个子列表组成,每个子列表都包含三个整数。可以通过下标来访问嵌套列表中的元素,例如,要访问第一个子列表中的第二个元素,可以使用以下代码:
nested_list[0][1] # Output: 2
可以使用嵌套列表来表示更复杂的数据结构,例如矩阵或表格。例如,以下是一个表示矩阵的嵌套列表:
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
嵌套列表也可以通过循环进行遍历和操作。例如,以下代码演示了如何遍历嵌套列表并打印出其中所有元素:
nested_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for sublist in nested_list:
for item in sublist:
print(item)
输出:
1
2
3
4
5
6
7
8
9
3.5 元组
3.5.1 元组的基本操作
元组(tuple)是 Python 中另一个重要的内置数据类型,它是一个有序且不可变的序列,使用圆括号 () 来表示。元组和列表相似,不同之处在于元组中的元素不能被修改或删除。
与列表一样,元组可以存储任意类型的数据,包括数字、字符串、列表和元组等。元组的创建方法和访问方式与列表类似,可以通过索引或切片来访问元素,也可以使用 for 循环来遍历元组中的元素。
创建元组
可以使用小括号 () 来创建元组,元素之间用逗号分隔。例如:
# 创建一个包含三个元素的元组
t = (1, 2, 3)
可以省略小括号,例如:
# 创建一个包含三个元素的元组
t = 1, 2, 3
如果元组只包含一个元素,则需要在元素后面加上逗号,否则它将被视为一个单独的对象,而不是元组。例如:
# 创建一个包含一个元素的元组
t = (1,)
2. 元组的取值
元组的取值可以通过索引或者切片实现。
通过索引取值示例:
tup = (1, 2, 3, 4, 5)
print(tup[0]) # 输出 1
print(tup[3]) # 输出 4
通过切片取值示例:
tup = (1, 2, 3, 4, 5)
print(tup[1:3]) # 输出 (2, 3)
print(tup[:3]) # 输出 (1, 2, 3)
print(tup[3:]) # 输出 (4, 5)
3. 元组的重复:*
元组可以通过 * 操作符进行重复,和列表相同。例如:
t = (1, 2, 3)
t2 = t * 3
print(t2) # 输出 (1, 2, 3, 1, 2, 3, 1, 2, 3)
4. 成员资格:in
元组也可以使用 in 和 not in 来判断某个元素是否存在于元组中,示例如下:
>>> t = (1, 2, 3, 4, 5)
>>> 3 in t
True
>>> 6 not in t
True
其中,in 返回 True 表示元素存在于元组中,not in 返回 True 表示元素不存在于元组中。
5. 元组(序列)的打包与解包
元组的打包是指将多个变量值赋给一个元组,而元组的解包则是将一个元组赋值给多个变量。
打包示例:
>>> tup = 1, 2, 3
>>> tup
(1, 2, 3)
>>> type(tup)
<class 'tuple'>
解包示例:
>>> x, y, z = tup
>>> x
1
>>> y
2
>>> z
3
打包和解包还可以结合使用,例如交换两个变量的值:
>>> a = 1
>>> b = 2
>>> a, b = b, a
>>> a
2
>>> b
1
这里将 b 和 a 打包成元组 (b, a),然后解包并分别赋值给 a 和 b。
元组常用操作符:
操作符 | 描述 | 重要程度 |
+ | 连接 | 高 |
* | 重复 | 高 |
in | 元素是否存在 | 高 |
not in | 元素是否不存在 | 高 |
< | 小于 | 中 |
<= | 小于等于 | 中 |
> | 大于 | 中 |
>= | 大于等于 | 中 |
== | 等于 | 高 |
!= | 不等于 | 高 |
() | 创建元组 | 高 |
元组的常用方法:
方法 | 描述 |
count() | 统计某个元素在元组中出现的次数 |
index() | 获取元素在元组中的索引位置 |
len() | 返回元组的长度 |
max() | 返回元组中元素的最大值 |
min() | 返回元组中元素的最小值 |
sorted() | 对元组进行排序 |
sum() | 返回元组中元素的和 |
其中,count()和index()是最常用的两个方法。
3.5.2 元组的嵌套
元组是一种序列类型,它可以包含任意类型的对象,包括其他元组。因此,元组可以嵌套,也就是说,一个元组可以作为另一个元组的元素。嵌套的元组可以使用索引来访问,如下面的示例所示:
t1 = (1, 2, 3)
t2 = ('a', 'b', 'c')
t3 = (t1, t2)
print(t3) # ((1, 2, 3), ('a', 'b', 'c'))
print(t3[0]) # (1, 2, 3)
print(t3[0][1]) # 2
在这个例子中,t1 和 t2 是两个简单的元组,t3 是一个嵌套元组,它包含了 t1 和 t2。通过 t3[0] 可以访问 t1,通过 t3[0][1] 可以访问 t1 中的第二个元素。
3.5.3 元组和列表的区别
元组和列表在Python中都是序列类型,它们有一些相似之处,例如:
都可以通过索引访问元素
都支持切片操作
都可以进行迭代
但是,元组和列表还是有一些重要的区别:
可变性:列表是可变的,也就是说,可以向列表中添加、删除或修改元素,而元组是不可变的,一旦创建,就不能再修改其中的元素。
语法:列表用方括号 [] 来表示,而元组用圆括号 () 来表示。
性能:元组比列表更轻量级,所以在存储大量数据时,元组的性能比列表更好。此外,元组可以作为字典的键,而列表不行。
总之,如果需要在程序中创建一个不可变的序列,或者需要存储大量数据的时候,应该使用元组。如果需要频繁地向其中添加、删除或修改元素,应该使用列表。
3.6 字典
字典(dictionary)是Python中内置的一种映射类型,它是一种可变的、无序的键值对集合,其中每个键(key)都唯一对应一个值(value)。字典用花括号 {} 来表示,其中每个键值对用冒号 : 分隔,每个键值对之间用逗号 , 分隔。字典的键可以是任意不可变类型,例如字符串、数字、元组(但元组中的元素必须是不可变类型),值可以是任意类型。
以下是一个字典的示例:
my_dict = {'apple': 2.5, 'banana': 1.8, 'orange': 3.2}
其中,'apple'、'banana'、'orange' 是字典的键,2.5、1.8、3.2 是对应的值。
3.6.1 字典的基本操作
字典是一种可变容器模型,可以存储任意类型对象的键/值对。字典用大括号{}表示,键值对之间用逗号分隔,冒号用于分割键和值。字典的基本操作包括创建字典、访问字典元素、修改字典元素、删除字典元素、判断键是否存在、获取所有键或所有值、获取所有键值对等。
创建字典:
可以使用大括号{}创建空字典,也可以使用字典函数dict()创建字典,同时也可以在创建字典时初始化键值对。例如:
# 创建空字典
empty_dict = {}
# 使用dict()函数创建字典
my_dict = dict()
# 创建初始化字典
info_dict = {'name': 'Tom', 'age': 25, 'gender': 'male'}
访问字典元素:
字典的元素是通过键来访问的,可以使用方括号[]来获取指定键对应的值。例如:
# 获取字典中的值
name = info_dict['name']
age = info_dict['age']
修改字典元素:
字典是可变的,可以修改字典中的键值对。例如:
# 修改字典中的值
info_dict['age'] = 26
删除字典元素:
可以使用del语句删除字典中的指定键值对,也可以使用pop()方法删除指定键值对,并返回对应的值。例如:
# 删除指定键值对
del info_dict['gender']
# 删除并返回值
age = info_dict.pop('age')
判断键是否存在:
可以使用in关键字或not in关键字来判断键是否存在于字典中。例如:
# 判断键是否存在
if 'name' in info_dict:
print('Name exists in info_dict.')
获取所有键或所有值:
可以使用keys()方法获取字典中所有的键,使用values()方法获取字典中所有的值。例如:
# 获取所有键
keys = info_dict.keys()
# 获取所有值
values = info_dict.values()
获取所有键值对:
可以使用items()方法获取字典中所有的键值对,返回一个包含所有键值对的元组列表。例如:
# 获取所有键值对
items = info_dict.items()
注意,字典的键必须是不可变类型,如数字、字符串、元组等,而列表等可变类型不能作为键。
8. dict.update方法合并字典
dict.update() 是字典类的一个方法,用于将一个字典中的键值对更新到另一个字典中。具体来说,它可以接受另一个字典或者可迭代对象作为参数,将其中的键值对添加到当前字典中。如果被更新的字典和更新字典中有相同的键,则会将更新字典中的值覆盖原字典中的值。
示例:
# 定义两个字典
dict1 = {'name': 'Alice', 'age': 20}
dict2 = {'gender': 'female', 'age': 21}
# 使用 update 方法将 dict2 合并到 dict1 中
dict1.update(dict2)
# 输出合并后的字典
print(dict1) # {'name': 'Alice', 'age': 21, 'gender': 'female'}
在上面的示例中,字典 dict1 中已经有一个键为 'age' 的键值对,而字典 dict2 中也有一个键为 'age' 的键值对。使用 update 方法将 dict2 合并到 dict1 中后,dict1 中的 'age' 键的值被更新为 21,即 dict2 中 'age' 键的值。
3.6.2 字典的其他操作
除了常见的基本操作外,字典还有一些其他的操作:
字典的长度:使用 len() 函数可以获取字典中键值对的个数。
删除键值对:使用 del 关键字可以删除字典中的指定键值对。
清空字典:使用 clear() 方法可以清空字典中的所有键值对。
获取键、值、键值对列表:分别使用 keys()、values()、items() 方法可以获取字典中所有键、所有值、所有键值对的列表。
检查字典中是否存在指定键或值:使用 in 关键字可以检查字典中是否存在指定的键或值。
复制字典:使用 copy() 方法可以复制一个字典,得到一个新的具有相同键值对的字典。
获取指定键的值,如果不存在则返回默认值:使用 get(key, default=None) 方法可以获取字典中指定键的值,如果该键不存在,则返回默认值(默认值为 None)。
设置指定键的默认值:使用 setdefault(key, default=None) 方法可以获取字典中指定键的值,如果该键不存在,则将键值对添加到字典中,并将默认值设置为该键的值。
弹出指定键的值:使用 pop(key, default=None) 方法可以获取并删除字典中指定键的值,如果该键不存在,则返回默认值(默认值为 None)。
弹出最后一个键值对:使用 popitem() 方法可以获取并删除字典中的最后一个键值对。
字典的排序:字典本身是无序的,但可以根据键或值的大小对其进行排序,具体的排序方法将在后续章节中介绍。Python 标准库中的 collections 模块提供了 OrderedDict 类来实现有序字典的功能,需要使用时需要先导入模块。
dict.fromkeys() 方法用于创建一个新字典,其中包含指定键和相应的值。它接受一个可迭代对象作为第一个参数,该可迭代对象包含作为键插入到新字典的元素,同时该方法也接受一个可选的参数,用作所有键对应值的初始值。如果没有提供初始值,则默认为 None。
例如,以下代码创建一个新字典,其中包含三个键,分别为 'a'、'b' 和 'c',每个键都对应初始值为 0:
keys = ['a', 'b', 'c']
values = 0
new_dict = dict.fromkeys(keys, values)
print(new_dict) # {'a': 0, 'b': 0, 'c': 0}
dict.fromkeys() 方法的返回值是一个新字典对象。
字典的常用方法:
方法 | 描述 |
dict.clear() | 清空字典 |
dict.copy() | 复制字典 |
dict.get(key, default=None) | 获取指定键的值,如果键不存在则返回默认值 |
dict.items() | 返回字典所有项列表 |
dict.keys() | 返回字典所有键列表 |
dict.values() | 返回字典所有值列表 |
dict.pop(key, default=None) | 弹出指定键的值,如果键不存在则返回默认值 |
dict.popitem() | 随机弹出一项并返回 |
dict.setdefault(key, default=None) | 获取指定键的值,如果键不存在则将键和默认值插入到字典中 |
dict.update(other_dict) | 将另一个字典的键值对更新到当前字典中 |
dict.contains(key) | 判断字典中是否包含指定键 |
dict.len() | 返回字典键值对数量 |
dict.str() | 返回字典字符串表示形式 |
注意:字典是可变对象,其常用方法会改变字典本身。
fotmat函数的用法
format() 函数是一种格式化字符串的方法,可用于将值插入到字符串中,以便创建更具可读性和可维护性的输出。format() 函数有五种常见的用法:
基本用法:将值按顺序插入字符串中
name = "Alice"
age = 25
print("My name is {} and I'm {} years old.".format(name, age))
输出:My name is Alice and I'm 25 years old.
使用参数位置标识符:指定值插入的位置
name = "Alice"
age = 25
print("My name is {0} and I'm {1} years old. {0} is my name again.".format(name, age))
输出:My name is Alice and I'm 25 years old. Alice is my name again.
设置参数
'site: {user} url: {url}'.format(user='oldboy', url='http://www.oldboyedu.com')
通过列表索引设置参数
可以通过列表索引来设置参数。例如:
my_list = ['oldboy', 'http://www.oldboyedu.com']
result = 'site: ({0}) url: ({1})'.format(my_list[0], my_list[1])
print(result)
输出结果为:
site: (oldboy) url: (http://www.oldboyedu.com)
在 format 函数中,使用 {0} 和 {1} 表示第一个和第二个参数,分别对应列表中的第一个和第二个元素。
通过字典设置参数
可以通过字典的键值对来设置参数,具体方法如下:
data = {'user': 'oldboy', 'url': 'http://www.oldboyedu.com'}
print('site: {user} url: {url}'.format(**data))
输出:
site: oldboy url: http://www.oldboyedu.com
在这个例子中,我们使用了 ** 语法将 data 字典作为参数传递给 format 函数。在字符串中,我们使用花括号 {} 来指定占位符,而这些占位符的名称正好是字典中的键。使用这种方法可以方便地在代码中传递参数,并且避免了位置参数的混乱。
**语法用于在函数调用时将字典展开成关键字参数。例如,如果有一个字典params = {'name': 'Alice', 'age': 25},则可以将它传递给一个函数foo作为关键字参数:
def foo(name, age):
print(f"{name} is {age} years old")
params = {'name': 'Alice', 'age': 25}
foo(**params) # 输出:Alice is 25 years old
在这个例子中,params字典被展开成关键字参数name='Alice'和age=25,然后被传递给foo函数。
format函数的数字格式化
https://blog.csdn.net/baidu_35901646/article/details/103598626
3.6.3 字典的嵌套
字典的值也可以是另一个字典,从而实现字典的嵌套。例如:
d = {'a': {'x': 1, 'y': 2}, 'b': {'x': 3, 'y': 4}}
这个字典 d 包含两个键值对,每个键值对的值都是一个字典。可以使用两个索引来访问嵌套字典中的值,例如:
>>> d['a']['x']
1
>>> d['b']['y']
4
也可以使用 keys() 方法和 values() 方法来分别获取嵌套字典中的键和值。例如:
>>> d.keys()
dict_keys(['a', 'b'])
>>> d.values()
dict_values([{'x': 1, 'y': 2}, {'x': 3, 'y': 4}])
3.7 集合
集合(Set)是 Python 中的一种无序可变容器,用于存储不重复的元素,它是由一对花括号 {} 构成,每个元素之间用逗号 , 分隔。集合中的元素必须是不可变类型,如整数、浮点数、字符串、元组等,而不能包含可变类型的元素,如列表、字典等。
与列表和元组不同,集合是无序的,因此无法通过索引来访问集合中的元素。集合中不允许有重复的元素,如果有重复的元素,Python 解释器会自动去除重复的元素。
集合支持多种基本操作,如添加元素、删除元素、求交集、并集、差集等。
3.7.1 集合的常用操作和方法
集合(Set)是 Python 中的一种无序、不重复的数据类型,它支持一些数学运算符和方法。
常用操作:
创建集合:使用花括号 {} 或 set() 函数。
集合的成员资格:使用 in 或 not in 运算符。
集合的长度:使用 len() 函数。
集合的判空:使用 if not set:。
集合的遍历:使用 for 循环。
集合的运算:支持交、并、差和对称差等运算符。
常用方法:
set.add(x):向集合添加元素 x。
set.update(other):将其他可迭代对象的元素添加到集合中。
set.remove(x):从集合中删除元素 x,如果不存在则引发 KeyError 异常。
set.discard(x):从集合中删除元素 x,如果不存在则什么也不做。
set.pop():随机删除并返回集合中的一个元素。
set.clear():清空集合。
set.copy():返回集合的浅拷贝。
set.union(other) 或 set | other:返回集合和其他集合或可迭代对象的并集。
set.intersection(other) 或 set & other:返回集合和其他集合或可迭代对象的交集。
set.difference(other) 或 set - other:返回集合和其他集合或可迭代对象的差集。
set.symmetric_difference(other) 或 set ^ other:返回集合和其他集合或可迭代对象的对称差集。
set.issubset(other) 或 set <= other:判断集合是否为其他集合或可迭代对象的子集。
set.issuperset(other) 或 set >= other:判断集合是否为其他集合或可迭代对象的超集。
set.isdisjoint(other):判断集合和其他集合或可迭代对象是否有交集。
3.7.2 集合的运算
集合的运算包括交集、并集、差集、对称差集等。
交集:两个集合中共同存在的元素组成的集合,使用 & 或 intersection() 方法实现。
并集:两个集合中所有元素组成的集合,使用 | 或 union() 方法实现。
差集:一个集合中存在,而另一个集合中不存在的元素组成的集合,使用 - 或 difference() 方法实现。
对称差集:两个集合中非共同存在的元素组成的集合,使用 ^ 或 symmetric_difference() 方法实现。
下面是一些示例代码:
# 创建两个集合
set1 = {1, 2, 3}
set2 = {3, 4, 5}
# 交集
print(set1 & set2)
print(set1.intersection(set2))
# 并集
print(set1 | set2)
print(set1.union(set2))
# 差集
print(set1 - set2)
print(set1.difference(set2))
# 对称差集
print(set1 ^ set2)
print(set1.symmetric_difference(set2))
输出结果如下:
{3}
{3}
{1, 2, 3, 4, 5}
{1, 2, 3, 4, 5}
{1, 2}
{1, 2}
{1, 2, 4, 5}
{1, 2, 4, 5}
集合的常用方法和内置函数如下:
方法/函数 | 描述 |
set.add(x) | 将元素 x 添加到集合 set 中 |
set.clear() | 移除集合 set 中的所有元素 |
set.copy() | 复制集合 set |
set.difference(other) | 返回集合 set 中存在,但集合 other 中不存在的元素 |
set.difference_update(other) | 移除集合 set 中存在,但集合 other 中也存在的元素 |
set.discard(x) | 移除集合 set 中元素 x,如果元素不存在,则不进行操作 |
set.intersection(other) | 返回集合 set 和集合 other 中都存在的元素 |
set.intersection_update(other) | 仅保留集合 set 和集合 other 中都存在的元素 |
set.isdisjoint(other) | 判断集合 set 和集合 other 是否没有相同元素 |
set.issubset(other) | 判断集合 set 是否为集合 other 的子集 |
set.issuperset(other) | 判断集合 set 是否为集合 other 的父集 |
set.pop() | 随机移除并返回集合 set 中的一个元素 |
set.remove(x) | 移除集合 set 中元素 x,如果元素不存在,则抛出 KeyError 异常 |
set.symmetric_difference(other) | 返回集合 set 和集合 other 中存在,但不同时存在的元素 |
set.symmetric_difference_update(other) | 对集合 set 和集合 other 中存在,但不同时存在的元素进行移除和添加 |
set.union(other) | 返回集合 set 和集合 other 中所有元素的并集 |
set.update(other) | 将集合 other 中的元素添加到集合 set 中 |
len(set) | 返回集合 set 的元素个数 |
sorted(set) | 返回集合 set 中的元素排序后的列表 |
all(set) | 判断集合 set 中所有元素是否都为 True |
any(set) | 判断集合 set 中是否存在至少一个元素为 True |
其中,常用的集合运算符有:
运算符 | 描述 |
& | 交集,返回包含两个集合中共同元素的集合 |
- | 差集,返回包含只在集合 A 中存在,而在集合 B 中不存在的元素的集合 |
^ | 对称差集,返回包含集合 A 和 B 中所有不属于交集的元素的集合 |
需要注意的是,集合是可变对象,可以使用上述方法对其进行修改,而集合中的元素必须是不可变对象。
3.7.3 集合的嵌套
集合是可变的,因此不能作为集合的元素。集合的元素必须是不可变的,如数字、字符串和元组等。
元组中只有当所有的元素都为不可变类型的时候,此时的元组才认为是可哈希的,如t=(l,2,3)才可以当作字典的 key 或集合的元素。这是因为在 Python 中,可哈希(hashable)的对象是指那些具有固定哈希值(hash value)且不可变的对象。可哈希的对象包括不可变类型,如整数、浮点数、字符串、元组等,而不可哈希的对象包括可变类型,如列表、字典、集合等。因此,如果一个元组中有一个不可哈希的元素(如列表),那么这个元组就不可哈希,不能作为字典的键或集合的元素。
在计算机科学中,哈希是一种从任何一种数据中创建小的数字“指纹”的方法。哈希函数将数据映射到一个固定大小的值(例如 32 位整数)。这个映射的目标是让数据难以被修改,数据越是难以被修改,哈希函数的效果就越好。哈希函数可以用于快速定位数据,例如在哈希表中搜索数据。
可哈希(hashable)对象必须满足两个条件:
对象的生命周期中散列值不能变化。
对象必须是可比较的。
可变对象无法满足第一个条件,因为它们的值可以在对象的生命周期中被更改。不可变对象(如数字、字符串、元组)满足条件,因此它们可以被用作字典的键或集合的元素。
在 Python 中,可哈希的对象都可以用 hash() 函数获取其哈希值。而不可哈希的对象将会导致 TypeError 错误。
3.8 推导式、三元表达式与深、浅拷贝
3.8.1 推导式
推导式(Comprehension)是 Python 中一种简洁的语法,用于创建一个数据结构,如列表、集合、字典等,通过对一个可迭代对象进行操作,可以将操作的结果转换为新的数据结构。常见的推导式包括列表推导式、集合推导式、字典推导式等。
列表推导式的基本语法如下:
[expression for item in iterable if condition]
其中 expression 是对 item 的操作,item 是 iterable 中的每个元素,condition 是一个可选的条件语句,用于过滤 item。
举个例子,可以使用列表推导式快速创建一个包含 1~10 的平方的列表:
squares = [x ** 2 for x in range(1, 11)]
print(squares) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
集合推导式和列表推导式类似,只不过使用了花括号 {} 来表示集合。字典推导式则使用键值对的形式来表示字典的元素,基本语法如下:
{key_expression: value_expression for expression in iterable if condition}
其中 key_expression 和 value_expression 分别是键和值的操作,expression 是 iterable 中的每个元素,condition 是一个可选的条件语句,用于过滤元素。
举个例子,可以使用字典推导式快速创建一个将名字映射为长度的字典:
names = ['Alice', 'Bob', 'Charlie']
name_lengths = {name: len(name) for name in names}
print(name_lengths) # {'Alice': 5, 'Bob': 3, 'Charlie': 7}
3.8.2 三元表达式
三元表达式是一种简洁的 if-else 语句的写法,可以用一行代码实现条件判断。基本语法如下:
result = true_value if condition else false_value
其中 true_value 和 false_value 分别是条件为 True 和 False 时的返回值,condition 是一个布尔表达式。
举个例子,可以使用三元表达式实现判断一个数是奇数还是偶数:
num = 5
even_or_odd = "even" if num % 2 == 0 else "odd"
print(even_or_odd) # 'odd'
3.8.3 深、浅拷贝
在 Python 中,赋值操作符“=”是一种浅拷贝(shallow copy)方法,它只是创建了一个对象的新引用,而不是复制整个对象。如果该对象是可变对象(如列表、字典等),那么在新对象上的修改也会影响到原对象。这是因为新对象和原对象在内存中共享同一块数据。
为了解决这个问题,可以使用深拷贝(deep copy)。深拷贝会复制整个对象及其子对象,创建一个新的独立对象,并在新对象上进行操作,不影响原对象。在 Python 中,可以使用标准库中的 copy 模块中的 deepcopy 方法来进行深拷贝。
以下是一个示例,展示了浅拷贝和深拷贝的区别:
import copy
# 浅拷贝
a = [1, 2, [3, 4]]
b = a.copy()
b[0] = 10
b[2][0] = 30
print(a) # [1, 2, [30, 4]]
print(b) # [10, 2, [30, 4]]
# 深拷贝
a = [1, 2, [3, 4]]
b = copy.deepcopy(a)
b[0] = 10
b[2][0] = 30
print(a) # [1, 2, [3, 4]]
print(b) # [10, 2, [30, 4]]
从上面的代码可以看出,浅拷贝只是复制了对象的引用,所以在修改子对象的时候,原对象也会被修改;而深拷贝则会复制整个对象,所以修改新对象不会影响原对象。