数值
Python 的数值数据类型是用来存储数值的。一旦创建,数值对象的身份和类型是不可改变的 。如果你改变了数值对象的值,Python 将创建一个新的数值对象。Python 支持三种不同的数值类型:
整型 (int) :被用来表示整数,包括正整数和负整数,不带小数点。在 Python 3 中,整数的长度是无限的,可以视为 Python 2 中的 Long 类型。此外,布尔类型(bool)实际上是整型的一种特殊形式,其中 True 和 False 分别被表示为 1 和 0。
浮点型 (float) :用来表示实数,由整数部分和小数部分组成。浮点型还可以使用科学计数法表示。例如,2.5e2 表示的是 2.5 乘以 10 的平方,等于 250。
复数 (complex) :复数由实部和虚部构成,表示形式可以是 a + bj,或者 complex(a,b)。在这里,实部 a 和虚部 b 都是浮点型。
num1 = - 100 # 整数
num2 = 200.01 # 浮点数
num3 = 0x A0F # 十六进制
num4 = 0o 37 # 八进制
# 引入库
import math
import random
# 数学常量 PI 和 e
pi = math.pi
e = math.e
# 绝对值
abs_val = abs (num1)
# 向上取整
ceil_val = math.ceil(num2)
# 返回最大数
max_val = max (num1, num2)
# x**y 运算后的值
pow_val = pow (num1, num2)
# 随机数
random_val = random.random()
# x弧度的正弦值。
sin_val = math.sin(pi / 2 )
字符串
字符串在计算机科学和编程中非常重要。在 Python 程序中,如果我们把单个或多个字符用单引号或者双引号包围起来,我们就创建了一个字符串。
定义
# 在 Python 中,可以使用单引号(')和双引号(")来定义字符串,它们的使用方式完全相同。
s1 = 'hello, world!'
s2 = "hello, world!"
# 使用三个单引号(''')或者三个双引号(""")可以创建一个多行字符串。
s3 = """
hello,
world!
"""
# 反斜杠(\)可以用来在字符串中插入特殊字符,这被称为转义字符。
s4 = ' \n\t\141\u9a86\u660a '
# 在字符串前加上字符 r 可以阻止反斜杠的转义效果。
s5 = r ' \n\\ hello, world! \\\n '
# 通过将字符串级联来创建新的字符串。
s6 = "this " "is " "string"
# 字符串是不可变的,这意味着你不能改变一个字符串的内容。
s6[ 2 ] = "c" # 这将引发一个错误
# 字符串可以通过索引进行访问,其中 0 是第一个字符的索引,-1 是最后一个字符的索引。
s1 = 'hello, world!'
print (s1[ 0 ]) # 输出:h
print (s1[ - 1 ]) # 输出:!
# Python也支持字符串的切片操作,你可以使用这种方式来获取字符串的一部分。
s1 = 'hello, world!'
print (s1[ 0 : 5 ]) # 输出:hello
# ===== 字符串切片示意图 =====
| L | e | t | t | e | r | s |
| -- -| -- -| -- -| -- -| -- -| -- -| -- -|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|- 7 |- 6 |- 5 |- 4 |- 3 |- 2 |- 1 |
转义
转义字符 描述 示例 \\
反斜杠符号 print("\\")
输出:\
\'
单引号 print('\'')
输出:'
\"
双引号 print("\"")
输出:"
\n
换行 print("\n")
输出一个新行\r
回车 print("Hello\rWorld!")
输出:World!
\t
横向制表符(Tab) print("Hello\tWorld!")
输出:Hello World!
\b
退格 (Backspace) print("Hello \bWorld!")
输出:Hello World!
\f
换页 print("Hello \fWorld!")
输出:Hello World!
\a
响铃 print("\a")
执行后电脑有响声\000
空 print("\000")
输出:“\v
纵向制表符 print("Hello \vWorld!")
输出:Hello World!
\other
其他的字符以普通格式输出 \xhh
二进制数,代表一个 ASCII 字符 print("\x48\x65\x6c\x6c\x6f")
输出:Hello
\ooo
八进制数,代表一个 ASCII 字符 print("\141\142\143")
输出:abc
\uhhhh
16 进制数,代表一个 Unicode 字符 print("\u6211\u4eec")
输出:我们
运算
运算符 描述 示例 +
连接字符串 "Hello " + "World!"
输出:Hello World!
*
重复字符串 "Hello " * 3
输出:Hello Hello Hello
[]
索引字符串 "Hello"[1]
输出:e
[:]
切片字符串 "Hello"[1:4]
输出:ell
in
成员运算符 - 如果字符串中包含给定的字符返回 True 'H' in 'Hello'
输出:True
not in
成员运算符 - 如果字符串中不包含给定的字符返回 True 'H' not in 'Hello'
输出:False
%
格式化字符串 "Hello, %s" % 'World!'
输出:Hello, World!
f-string
格式化字符串的新方式(Python 3.6+) f"Hello, {'World!'}
输出:Hello, World!
f-strings
在 Python 3.6 及以后的版本中,格式化字符串引入了更为简洁的方式,即使用 f
字符作为字符串的前缀,创建所谓的格式化字符串字面值(f-string)。通过 f-string,可以在字符串中直接插入变量值或表达式,并可以通过冒号和数字来指定输出宽度等格式化选项。
# {a:10} 表示将变量 a 插入到字符串中,并占用 10 个字符的宽度。不足 10 个字符,将使用空格进行填充。
a, b = 5 , 10
print ( f ' { a :10 } * { b :10 } = { a * b } ' )
PEP 701 的更新
在 Python 3.11 版本中,f-strings 还存在一些限制,导致在某些情况下使用起来不够灵活。PEP 701 对 f-strings 进行了一些更新,解除了一些限制,使得 f-strings 可以更灵活地使用,包括以下方面的更新:
在 Python 3.12 版本中,对 f-strings 进行了更新,解除了之前的一些限制,使得 f-strings 更加灵活和强大。更新主要包括以下方面:
引号重用
在 Python 3.11 中,f-string 的表达式组件使用与包含 f-string 相同的引号会导致 SyntaxError。而在 Python 3.12 中,可以重用引号,不再限制引号的使用。
songs = [ 'Take me back to Eden' , 'Alkaline' , 'Ascensionism' ]
result1 = f "This is the playlist: { ', ' .join(songs) } "
print (result1)
# 输出:'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'
多行表达式和注释
在 Python 3.11 中,f-string 的表达式必须在一行内定义,即使外部表达式可以跨多行,这会使得代码可读性变差。而在 Python 3.12 中,可以定义跨多行的表达式,并且可以包含注释,提高了代码的可读性。
result2 = f "This is the playlist: { ', ' .join([
'Take me back to Eden' , # My, my, those eyes like fire
'Alkaline' , # Not acid nor alkaline
'Ascensionism' # Take to the broken skies at last
]) } "
print (result2)
# 输出:'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'
反斜杠和 Unicode 字符
在 Python 3.11 中,f-string 的表达式不能包含任何反斜杠字符,也不能包含 Unicode 转义序列。而在 Python 3.12 中,可以包含反斜杠和 Unicode 字符,使得表达式更加灵活。
songs = [ 'Take me back to Eden' , 'Alkaline' , 'Ascensionism' ]
result3 = f "This is the playlist: { ' \n ' .join(songs) } "
print (result3)
# 输出:
# This is the playlist: Take me back to Eden
# Alkaline
# Ascensionism
result4 = f "This is the playlist: { ' \N{BLACK HEART SUIT} ' .join(songs) } "
print (result4)
# 输出:'This is the playlist: Take me back to Eden♥Alkaline♥Ascensionism'
以上代码展示了 Python 3.12 中 f-strings 的更新。可以看到,我们可以在 f-string 中使用引号重用,多行表达式和注释,以及包含反斜杠和 Unicode 字符的表达式,这些更新使得 f-strings 更加灵活和强大,更方便地进行字符串格式化。同时,通过使用 PEG 解析器实现的更新,使得错误消息更加准确,有助于代码调试。
常用方法
函数 描述 示例 len(str) 返回字符串长度 len('hello, world!')
输出结果:13str.capitalize() 返回首字母大写的字符串 'hello, world!'.capitalize()
输出结果:Hello, world!str.title() 返回每个单词首字母大写的字符串 'hello, world!'.title()
输出结果:Hello, World!str.upper() 返回字符串变大写后的拷贝 'hello, world!'.upper()
输出结果:HELLO, WORLD!str.find(sub) 查找子串在字符串中的起始位置,未找到返回 -1 'hello, world!'.find('or')
输出结果:8str.startswith(prefix) 检查字符串是否以指定的前缀开头 'hello, world!'.startswith('He')
输出结果:Falsestr.endswith(suffix) 检查字符串是否以指定的后缀结尾 'hello, world!'.endswith('!')
输出结果:Truestr.center(width, fillchar) 将字符串以指定宽度居中并在两侧填充指定字符 'hello'.center(10, '*')
输出结果:hello str.rjust(width, fillchar) 将字符串以指定宽度靠右并在左侧填充指定字符 'hello'.rjust(10, '*')
输出结果:*****hellostr.isdigit() 检查字符串是否由数字构成 'abc123456'.isdigit()
输出结果:Falsestr.isalpha() 检查字符串是否由字母构成 'abc123456'.isalpha()
输出结果:Falsestr.isalnum() 检查字符串是否由字母和数字构成 'abc123456'.isalnum()
输出结果:Truestr.strip() 返回修剪左右两侧空格之后的字符串 ' jackfrued@126.com '.strip()
输出结果:‘jackfrued@126.com ’
列表
列表(list
)是一种结构化的、非标量类型,它是值的有序序列,每个值都可以通过索引进行标识,定义列表可以将列表的元素放在 []
中,多个元素用 ,
进行分隔,可以使用 for
循环对列表元素进行遍历,也可以使用 []
或 [:]
运算符取出列表中的一个或多个元素。
定义
# 列表定义
list1 = [ 'abcd' , 786 , 2.23 , 'runoob' , 70.2 ]
tinylist = [ 123 , 'runoob' ]
# 输出完整列表
print (list1) # 输出结果:['abcd', 786, 2.23, 'runoob', 70.2]
# 输出列表第一个元素
print (list1[ 0 ]) # 输出结果:'abcd'
# 从第二个开始输出到第三个元素
print (list1[ 1 : 3 ]) # 输出结果:[786, 2.23]
# 输出从第三个元素开始的所有元素
print (list1[ 2 :]) # 输出结果:[2.23, 'runoob', 70.2]
# 输出两次列表
print (tinylist * 2 ) # 输出结果:[123, 'runoob', 123, 'runoob']
# 连接列表
print (list1 + tinylist) # 输出结果:['abcd', 786, 2.23, 'runoob', 70.2, 123, 'runoob']
# 通过循环用下标遍历列表元素
for index in range ( len (list1)):
print (list1[index])
# 通过for 循环遍历列表元素
for elem in list1:
print (elem)
# 通过 enumerate 函数处理列表之后再遍历可以同时获得元素索引和值
for index, elem in enumerate (list1):
print (index, elem)
运算
# 创建列表
list1 = [ 1 , 2 , 3 ]
list2 = [ 4 , 5 , 6 ]
# 连接列表,返回一个新的列表
list3 = list1 + list2
print (list3) # 输出:[1, 2, 3, 4, 5, 6]
# 复制列表,返回一个新的列表
list4 = list1 * 3
print (list4) # 输出:[1, 2, 3, 1, 2, 3, 1, 2, 3]
# 计算元素个数
length = len (list1)
print (length) # 输出:3
# 判断元素是否在列表中
result = 4 in list1
print (result) # 输出:False
result = 2 in list1
print (result) # 输出:True
# 访问元素,可以使用索引,索引从0开始
elem = list1[ 0 ]
print (elem) # 输出:1
# 切片操作
list5 = list1[ 1 : 3 ]
print (list5) # 输出:[2, 3]
# 切片时可以指定步长
list6 = list1[ 0 : 3 : 2 ]
print (list6) # 输出:[1, 3]
# 切片时可以省略开始或结束索引
list7 = list1[: 2 ]
list8 = list1[ 1 :]
print (list7) # 输出:[1, 2]
print (list8) # 输出:[2, 3]
# 反向切片
list9 = list1[:: - 1 ]
print (list9) # 输出:[3, 2, 1]
# 修改元素值
list1[ 0 ] = 100
print (list1) # 输出:[100, 2, 3]
# 列表末尾添加元素
list1.append( 4 )
print (list1) # 输出:[100, 2, 3, 4]
# 列表末尾删除元素
list1.pop()
print (list1) # 输出:[100, 2, 3]
# 指定位置插入元素
list1.insert( 1 , 200 )
print (list1) # 输出:[100, 200, 2, 3]
# 删除指定位置的元素
del list1[ 2 ]
print (list1) # 输出:[100, 200, 3]
# 清空列表
list1.clear()
print (list1) # 输出:[]
常用方法
函数 描述 len(list)
返回列表元素的个数。 list.append(x)
在列表末尾添加元素 x
。 list.insert(i, x)
在指定位置 i
前插入元素 x
。 list.extend(iterable)
将可迭代对象中的元素逐个添加到列表。 list.remove(x)
删除列表中第一个值为 x
的元素。 list.pop([i])
移除并返回列表中指定位置 i
处的元素。如果未指定索引,默认删除并返回最后一个元素。 list.clear()
清空列表中的所有元素。 list.index(x[, start[, end]])
返回列表中第一个值为 x
的元素的索引。如果未找到该元素,会引发 ValueError
异常。 list.count(x)
返回元素 x
在列表中出现的次数。 list.sort(key=None, reverse=False)
对列表进行排序,如果指定参数 key
则按照 key
进行排序,如果指定参数 reverse
则为降序。 list.reverse()
将列表中的元素倒序排列。 list.copy()
返回列表的浅拷贝,即创建一个新列表并复制原列表中的元素。
元组
Python 中的元组是一种容器数据类型,使用小括号 ()
定义,类似于列表,但元组的元素不能修改,是不可变的。元组用于存储多个数据,可以包含不同类型的元素。与列表不同,元组在定义时可以省略括号,但在实际使用中建议加上括号,以增强代码的可读性。
定义
# 定义元组
t = ( '骆昊' , 38 , True , '四川成都' )
# 定义空元组
t1 = ()
# 元组中只包含一个元素时,需要在元素后面添加逗号 `,`,否则括号会被当作运算符使用。
tup1 = ( 50 ) # 不加逗号,类型为整型
tup1 = ( 50 ,) # 加上逗号,类型为元组
# 遍历元组中的值
for member in t:
print (member)
# 重新给元组赋值
# t[0] = '王大锤' # TypeError,元组不可修改
# 变量t重新引用了新的元组,原来的元组将被垃圾回收
t = ( '王大锤' , 20 , True , '云南昆明' )
# 将元组转换成列表
person = list (t)
# 将列表转换成元组
fruits_list = [ 'apple' , 'banana' , 'orange' ]
fruits_tuple = tuple (fruits_list)
# 创建一个新的元组
tup1 = ( 12 , 34.56 )
tup2 = ( 'abc' , 'xyz' )
tup3 = tup1 + tup2
# 删除元组
tup = ( 'Google' , 'Runoob' , 1997 , 2000 )
del tup
运算
# 创建元组
tup1 = ( 1 , 2 , 3 )
tup2 = ( 4 , 5 , 6 )
# 连接元组,返回一个新的元组
tup3 = tup1 + tup2
print (tup3) # 输出:(1, 2, 3, 4, 5, 6)
# 复制元组,返回一个新的元组
tup4 = tup1 * 3
print (tup4) # 输出:(1, 2, 3, 1, 2, 3, 1, 2, 3)
# 计算元素个数
length = len (tup1)
print (length) # 输出:3
# 判断元素是否在元组中
result = 4 in tup1
print (result) # 输出:False
result = 2 in tup1
print (result) # 输出:True
# 访问元素,可以使用索引,索引从0开始
elem = tup1[ 0 ]
print (elem) # 输出:1
# 切片操作
tup5 = tup1[ 1 : 3 ]
print (tup5) # 输出:(2, 3)
# 切片时可以指定步长
tup6 = tup1[ 0 : 3 : 2 ]
print (tup6) # 输出:(1, 3)
# 切片时可以省略开始或结束索引
tup7 = tup1[: 2 ]
tup8 = tup1[ 1 :]
print (tup7) # 输出:(1, 2)
print (tup8) # 输出:(2, 3)
# 反向切片
tup9 = tup1[:: - 1 ]
print (tup9) # 输出:(3, 2, 1)
常用方法
函数 描述 len(tuple)
返回元组中元素的个数。 tuple.count(x)
返回元组中元素 x
出现的次数。 tuple.index(x[, start[, end]])
返回元组中第一个值为 x
的元素的索引。如果未找到该元素,会引发 ValueError
异常。 tuple + tuple
将两个元组连接成一个新的元组。 tuple * n
将元组重复 n
次。 x in tuple
判断元素 x
是否在元组中,如果在返回 True
,否则返回 False
。 x not in tuple
判断元素 x
是否不在元组中,如果不在返回 True
,否则返回 False
。
集合
集合(set)是由不重复元素组成的无序容器。基本用法包括成员检测、消除重复元素。集合对象支持合集、交集、差集、对称差分等数学运算。
定义
集合可以通过花括号 {}
或 set()
函数创建。注意,创建空集合只能用 set()
,不能用 {}
,因为 {}
创建的是空字典。
# 创建集合
set1 = { 1 , 2 , 3 , 4 , 5 }
set2 = { 3 , 4 , 5 , 6 , 7 }
set3 = { 5 , 6 , 7 , 8 , 9 }
# 判断元素是否在集合内
3 in set1 # True
10 in set1 # False
# 添加元素
set1.add( 6 ) # {1, 2, 3, 4, 5, 6}
set1.add( 7 ) # {1, 2, 3, 4, 5, 6, 7}
set1.add( 3 ) # {1, 2, 3, 4, 5, 6, 7},重复的元素不会被添加
# 删除元素
set1.remove( 4 ) # {1, 2, 3, 5, 6, 7}
set1.discard( 6 ) # {1, 2, 3, 5, 7}
set1.discard( 8 ) # {1, 2, 3, 5, 7},如果元素不存在,discard 方法不会引发异常
# 元素个数
len (set1) # 5
# 清空集合
set1.clear() # set()
运算
set1 = { 1 , 2 , 3 , 4 , 5 }
set2 = { 3 , 4 , 5 , 6 , 7 }
set3 = { 5 , 6 , 7 , 8 , 9 }
# 交集
set1 & set2 # {3, 4, 5}
# 并集
set1 | set2 # {1, 2, 3, 4, 5, 6, 7}
# 差集
set1 - set2 # {1, 2}
# 对称差运算(在 set1 或 set2 中,但不会同时出现在二者中)
set1 ^ set2 # {1, 2, 6, 7}
# 判断子集和超集
set2 <= set1 # False,set2 是 set1 的子集吗?
set3 <= set1 # False,set3 是 set1 的子集吗?
set1 >= set2 # False,set1 是 set2 的超集吗?
set1 >= set3 # False,set1 是 set3 的超集吗?
常用方法
函数 描述 set.add(x) 将元素 x 添加到集合中 set.remove(x) 删除集合中的元素 x,如果 x 不在集合中会引发 KeyError set.discard(x) 删除集合中的元素 x,如果 x 不在集合中不会引发异常 set.pop() 随机删除集合中的一个元素,并返回删除的元素 set.clear() 清空集合中的所有元素 len(set) 返回集合中元素的个数 x in set 判断元素 x 是否在集合中,如果在返回 True,否则返回 False set1.isdisjoint(set2) 判断两个集合是否没有共同的元素,如果没有返回 True,否则返回 False set1.issubset(set2) 判断集合 set1 是否是集合 set2 的子集,如果是返回 True,否则返回 False set1.issuperset(set2) 判断集合 set1 是否是集合 set2 的超集,如果是返回 True,否则返回 False set1.union(set2) 返回集合 set1 和 set2 的并集 set1.intersection(set2) 返回集合 set1 和 set2 的交集 set1.difference(set2) 返回集合 set1 和 set2 的差集,即在 set1 中但不在 set2 中的元素 set1.symmetric_difference(set2) 返回集合 set1 和 set2 的对称差集,即在 set1 或 set2 中,但不会同时出现在二者中的元素 set1.update(set2) 将集合 set2 中的元素添加到 set1 中 set1.intersection_update(set2) 将集合 set1 中不在 set2 中的元素删除 set1.difference_update(set2) 将集合 set1 和 set2 的差集中的元素从 set1 中删除 set1.symmetric_difference_update(set2) 将集合 set1 和 set2 的对称差集中的元素添加到 set1 中 set.copy() 返回集合的浅拷贝 set.pop() 随机删除并返回集合中的一个元素
字典
字典是另一种可变容器模型,且可存储任意类型对象 。字典与列表、集合不同的是,它是一种键 - 值(key-value)对应的数据结构。每个元素都是由一个键和一个值组成的键值对 ,键和值通过冒号分开。键必须是唯一的,但值则不必。
定义
# 使用大括号创建字典
person = { 'name' : 'John' , 'age' : 30 , 'city' : 'New York' }
# 使用 dict() 创建字典
empty_dict = dict ()
# 访问字典中的元素
print (person[ 'name' ]) # 输出:John
print (person[ 'age' ]) # 输出:30
print (person[ 'city' ]) # 输出:New York
运算
# 修改字典中的元素
person[ 'age' ] = 31
print (person) # 输出:{'name': 'John', 'age': 31, 'city': 'New York'}
# 添加新的键值对
person[ 'job' ] = 'Engineer'
print (person) # 输出:{'name': 'John', 'age': 31, 'city': 'New York', 'job': 'Engineer'}
# 删除字典中的元素
del person[ 'city' ]
print (person) # 输出:{'name': 'John', 'age': 31, 'job': 'Engineer'}
# 清空字典
person.clear()
print (person) # 输出:{}
# 遍历字典的键
for key in person:
print (key)
# 遍历字典的值
for value in person.values():
print (value)
# 遍历字典的键值对
for key, value in person.items():
print (key, value)
# 判断键是否存在
if 'name' in person:
print ( "Name exists." )
常用方法
方法 描述 keys()
返回字典所有键的列表 values()
返回字典所有值的列表 items()
返回字典所有键值对的元组列表 get(key, default=None)
返回指定键的值,如果键不存在,返回默认值 pop(key)
删除指定键的值,并返回该键对应的值 popitem()
随机删除一个键值对,并返回该键值对 clear()
删除字典中的所有键值对 update(other_dict)
将其他字典的键值对更新到当前字典 copy()
返回字典的浅拷贝(复制字典中的键值对)
推导式
推导式是一种强大的 Python 特性,可以快速、简洁地创建新的数据序列。它可以从一个数据序列构建另一个新的数据序列的结构体。
列表
列表推导式是最常用的推导式,它通过在一个可迭代对象上应用表达式来创建一个新的列表。
# 语法
new_list = [out_exp_res for out_exp in input_list]
new_list = [out_exp_res for out_exp in input_list if condition]
# 示例
multiples = [i for i in range ( 30 ) if i % 3 == 0 ]
print (multiples) # 输出:[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
字典
# 语法
new_dict = {key_expr: value_expr for value in collection}
new_dict = {key_expr: value_expr for value in collection if condition}
# 示例
dic = {x: x ** 2 for x in ( 2 , 4 , 6 )}
print (dic) # 输出:{2: 4, 4: 16, 6: 36}
集合
# 语法
new_set = {expression for item in sequence}
new_set = {expression for item in sequence if conditional}
# 示例
a = {x for x in 'abracadabra' if x not in 'abc' }
print (a) # 输出:{'d', 'r'}
元组
# 语法
new_tuple = (expression for item in sequence)
new_tuple = (expression for item in sequence if conditional)
# 示例
a = (x for x in range ( 1 , 10 ))
print (a) # 输出:<generator object <genexpr> at 0x7f900dfdd200>
print ( tuple (a)) # 输出:(1, 2, 3, 4, 5, 6, 7, 8, 9)
其他
f = [x for x in range ( 1 , 10 )]
print (f)
f = [x + y for x in 'ABCDE' for y in '1234567' ]
print (f)
f = [x ** 2 for x in range ( 1 , 1000 )]
print (sys.getsizeof(f)) # 查看对象占用内存的字节数
print (f)
# 生成器表达式,不占用额外内存
f = (x ** 2 for x in range ( 1 , 1000 ))
print (sys.getsizeof(f)) # 相比列表生成式,生成器不占用存储数据的空间
print (f)
for val in f:
print (val)
迭代器
可迭代对象是 Python 中的一种数据结构,例如列表、元组、字典、字符串等都是可迭代对象。迭代器是一种特殊的可迭代对象,它可以通过调用 iter()
函数获取,然后使用 next()
函数逐个访问元素。迭代器在其生命周期中,会有四个状态:GEN_CREATED
、GEN_RUNNING
、GEN_SUSPENDED
和 GEN_CLOSED
。
graph LR
A[生成器已创建] --> B[解释器执行中]
B --> C[在 yield 表达式处暂停]
C --> D[解释器执行中]
D --> C
D --> E[生成器执行结束]
iter() :创建迭代器。
next() :输出迭代器的下一个元素。
s = 'abc'
it = iter (s)
print (it) # 输出:<str_iterator object at 0x10c90e650>
print ( next (it)) # 输出:'a'
print ( next (it)) # 输出:'b'
print ( next (it)) # 输出:'c'
# 抛出异常
# 迭代器用尽后会引发 StopIteration 异常
try :
print ( next (it))
except StopIteration :
print ( "迭代器用尽了。" )
生成器
生成器是一种特殊的迭代器,它是一个可以像迭代器一样使用 for 循环来获取元素的函数。生成器函数使用 yield
关键字将一个普通函数改造成生成器函数,yield
相当于 return
但有所不同,yield
虽然返回了值但函数并没有结束,而是暂停在 yield
处,下次调用 next()
或循环迭代时会从 yield
处继续执行。生成器在其生命周期中会有四个状态:GEN_CREATED
、GEN_RUNNING
、GEN_SUSPENDED
和 GEN_CLOSED
。
graph LR
A[生成器函数被调用] --> B[生成器已创建]
B --> C[解释器执行中]
C --> D[在 yield 表达式处暂停]
D --> C
C --> E[生成器执行结束]
F[生成器已创建] --> G[GEN_CREATED]
G --> H[生成器正在执行]
H --> I[GEN_RUNNING]
I --> J[在 yield 表达式处暂停]
J --> H
I --> K[生成器执行结束]
K --> L[GEN_CLOSED]
生成器在其生命周期中,会有如下四个状态:
GEN_CREATED:生成器已创建,还未被激活。
GEN_RUNNING:解释器正在执行(只有在多线程应用中才能看到这个状态)。
GEN_SUSPENDED:在 yield 表达式处暂停。
GEN_CLOSED:生成器执行结束。
def fibonacci (n):
a, b, counter = 0 , 1 , 0
while True :
if counter > n:
return
yield a
a, b = b, a + b
counter += 1
for i in fibonacci( 10 ):
print (i, end = " " ) # 输出:0 1 1 2 3 5 8 13 21 34 55