Python的数据结构,推导式、迭代器和生成器

本文最后更新于 2026年5月4日

未完待续

【新年开篇】让我们拿出跃马扬鞭的勇气,激发万马奔腾的活力,保持马不停蹄的干劲,一起为梦想奋斗、为幸福打拼,把宏伟愿景变成美好现实。

1.概述

在Python中,有四种常见的数据结构

数据结构 是否可变 是否允许重复 是否有序 定义符号
列表(List) 可变 允许 有序 []
元组(Tuple) 不可变 允许 有序 ()
字典(Dict) 可变 键不允许,值允许 有序 {}
集合(Set) 可变 不允许 无序 {}

2.列表(List)

列表是一种有序的数据结构,元素写在[]中间,用,隔开通过下标访问。

列表创建有三种,直接创建,通过list()方法,以及推导式。

列表的特点:

  • 可以被索引(从左到右和从右到左)和切片(substring)
  • 可以使用+操作符进行拼接
  • 列表中的元素是可变的
  • 元素可以是任意类型
  • 元素允许重复

2.1 创建

#直接创建
list1 = [1,2,3,4,5]
list2 = ['abc', 2, 1.55]

python还有几种常见创建list方式:

list()方法创建一个空的集合

empty_list = list()
print(empty_list)

list()方法从字符串创建数组

s = 'hello'
l = list(s)
print(l) #['h', 'e', 'l', 'l', 'o']

从set集合创建

s = {1,2,3,4}
l = list(s)
print(l) #[1, 2, 3, 4]

从tuple元组创建

t = (1,2,3,4)
l = list(t)
print(l) #[1, 2, 3, 4]

从dic字典创建,只取每个key作为元素

d = {'a':1, 'b':2, 'c':3}
l = list(d)
print(l) #['a', 'b', 'c']

从dic字典创建,取每个键值对作为元素

d = {'a':1, 'b':2, 'c':3}
l = list(d.items())
print(l) #[('a', 1), ('b', 2), ('c', 3)]

从dic字典创建,取每个value作为元素

d = {'a':1, 'b':2, 'c':3}
l = list(d.values())
print(l) #[1, 2, 3]

通过range()创建list

sample_list = list(range(10))
print(sample_list) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

带类型标识符

from typing import List,  Union

#  只包含整数的列表
lst1: List[int] = [1, 2, 3, 4, 5]

# 包含其他类型
lst2: List[ Union[int, str, List[int] ] ] = [1, 2, 3, 4, '5']

2.2 列表常见方法

索引和切片


# 索引 => 1
print(list1[0])

# 第2到第4的元素,不含第4个 => [2, 3]
print(list1[1:3])

# 从第3个元素开始到末尾 => [3, 4, 5]
print(list1[2:])

# list1复制成两份拼接一起 => [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
print(list1 * 2)

# 拼接 => [1, 2, 3, 4, 5, 'abc', 2, 1.55]
print(list1 + list2)

Python列表可以倒序索引,从-1开始,且元素可变

list1[-1] = 100
print(list1[-1]) #100

列表可变,因此可以进行添加和删除元素等操作

删除第一个值为2的元素

l = [1,2,3,4,5,2]
l.remove(2)
print(l) #[1, 3, 4, 5, 2]

追加元素

l = [1,2,3,4,5]
l.append(4)
print(l) #[1, 2, 3, 4, 5, 4]

在某个元素前添加

l = [1,2,3,4,5]
l.insert(3, 'a')
print(l) #[1, 2, 3, 'a', 4, 5]

加号运算,两个列表拼接成为一个全新的列表对象

list1 = [1,2,3]
list2 = [3,4,5]
list3 = list1 + list2

print(list1)
print(list2)
print(list3)

print(id(list1))
print(id(list2))
print(id(list3))
[1, 2, 3]
[3, 4, 5]
[1, 2, 3, 3, 4, 5]
2575803669824
2575803939264
2575796778880

删除指定位置的元素并返回

l = [1,2,3,4,5,2]
sl = l.pop(2)  # 删除指定位置的元素并返回
print(sl)
print(l)
3
[1, 2, 4, 5, 2]

长度,最大值,最小值,求和

list1 = [6, 2, 4, 7, 8]
print(f"获取列表长度: {len(list1)}")  
print(f"列表的最大值: {max(list1)}") 
print(f"列表的最小值: {min(list1)}")  
print(f"列表的所有元素的和: {sum(list1)}") 
获取列表长度: 5
列表的最大值: 8
列表的最小值: 2
列表的所有元素的和: 27

排序,反转

sort_list=[10,8,7,1,20]
sort_list.sort()  # 列表排序
print(f"列表排序: {sort_list}")  
sort_list.reverse()  # 列表反转
print(f"列表反转: {sort_list}") 
列表排序: [1, 7, 8, 10, 20]
列表反转: [20, 10, 8, 7, 1]

2.3 遍历列表

1.使用for循环遍历列表

lst=[6, 2, 3, 4, 7, 8]

for item in lst:
    print(f"遍历列表元素: {item}")  
遍历列表元素: 6
遍历列表元素: 2
遍历列表元素: 3
遍历列表元素: 4
遍历列表元素: 7
遍历列表元素: 8

2.下标遍历

lst=[6, 2, 3, 4, 7, 8]

for i in range(len(lst)):
    print(f"使用下标遍历列表元素: {lst[i]}")  
使用下标遍历列表元素: 6
使用下标遍历列表元素: 2
使用下标遍历列表元素: 3
使用下标遍历列表元素: 4
使用下标遍历列表元素: 7
使用下标遍历列表元素: 8

3.使用enumerate函数遍历列表,可以同时遍历下标和元素,还可以start=指定从哪个下标开始

lst=[6, 2, 3, 4, 7, 8]

for index, item in enumerate(lst):
    print(f"使用enumerate函数遍历列表元素: {index} -> {item}")

for index, item in enumerate(lst, start=2):
    print(f"使用enumerate函数遍历列表元素 start=2 : {index} -> {item}")
使用enumerate函数遍历列表元素: 0 -> 6
使用enumerate函数遍历列表元素: 1 -> 2
使用enumerate函数遍历列表元素: 2 -> 3
使用enumerate函数遍历列表元素: 3 -> 4
使用enumerate函数遍历列表元素: 4 -> 7
使用enumerate函数遍历列表元素: 5 -> 8
使用enumerate函数遍历列表元素 start=2 : 2 -> 6
使用enumerate函数遍历列表元素 start=2 : 3 -> 2
使用enumerate函数遍历列表元素 start=2 : 4 -> 3
使用enumerate函数遍历列表元素 start=2 : 5 -> 4
使用enumerate函数遍历列表元素 start=2 : 6 -> 7
使用enumerate函数遍历列表元素 start=2 : 7 -> 8

4.zip函数同时遍历多个列表

list_a = [1, 2, 3]
list_b = [4, 5, 6]
for item_a, item_b in zip(list_a, list_b):
    print(f"使用zip函数遍历多个列表元素: {item_a}, {item_b}") #
使用zip函数遍历多个列表元素: 1, 4
使用zip函数遍历多个列表元素: 2, 5
使用zip函数遍历多个列表元素: 3, 6

3.元组(Tuple)

元组是一种和列表相似的数据结构,元素是任意类型,有序,允许重复,区别是:元组元素不可变

3.1 创建

几种简单创建方式

tup = tuple() #通过tuple()方法创建

tup = ()  #空元组

tup = (1, 2, 3) #创建元组

tup = (1,)  # 元组内只有一个元素,结尾要加逗号

tup = 1, 2, 3 #一种不被推荐的创建方式

tup = (1, "hello", 3.14, True) #支持不同类型

tup = (1, 2, 2, 3, 3, 3) # 重复元素

从其他数据结构创建

#  使用tuple()函数接收列表创建元组
tup = tuple([1, 2, 3])
print("使用tuple()函数接收列表参数,创建元组:", tup)  

#  使用tuple()函数接收字符串创建元组
tup = tuple("hello")
print("使用tuple()函数接收字符串作为参数,创建元组:", tup)  

#   使用tuple()函数接收集合创建元组
tup = tuple({1, 2, 3})
print("使用tuple()函数接收集合作为参数,创建元组:", tup) 

#  使用tuple()函数接收元组创建元组
from_tuple = (1, 2, 3)
tup = tuple(from_tuple)
print("使用tuple()函数接收元组作为参数,创建元组:", tup)   

# 使用tuple()函数接收字典创建元组,字典的key值会作为元组的元素
tup = tuple({"a": 1, "b": 2})   
print("使用tuple()函数接收字典作为参数,创建元组:", tup)   

#  使用tuple()函数接收字典的values创建元组
from_dict = {"a": 1, "b": 2}
tup = tuple(from_dict.values())
print("使用tuple()函数接收字典的values作为参数,创建元组:", tup)   

# 使用tuple()函数接收字典的items创建元组
tup = tuple(from_dict.items())
print("使用tuple()函数接收字典的items作为参数,创建元组:", tup)
使用tuple()函数接收列表参数,创建元组: (1, 2, 3)
使用tuple()函数接收字符串作为参数,创建元组: ('h', 'e', 'l', 'l', 'o')
使用tuple()函数接收集合作为参数,创建元组: (1, 2, 3)
使用tuple()函数接收元组作为参数,创建元组: (1, 2, 3)
使用tuple()函数接收字典作为参数,创建元组: ('a', 'b')
使用tuple()函数接收字典的values作为参数,创建元组: (1, 2)
使用tuple()函数接收字典的items作为参数,创建元组: (('a', 1), ('b', 2))

带类型标识符创建


from typing import  Tuple

#  包含整数、字符串、布尔值的元组
tup: Tuple[int, str, bool, List[int] ] = (25, "z3", True)

3.2 常见方法

1.访问

tup = (1, 2, 3)
tup[0]

2.元组元素不可变,下面程序会出错

tup = (1, 2)
tup[1] = 5

元组中元素的idhash不可变,但是内容可变,例如元组([1, 2], 3)中的list[1, 2]可以追加和编辑元素

3.索引和切片

tup = ('a', 'b', 'c')
print(f"元组访问有序性: {tup}")   
print(f"元组支持索引: {tup[0]}")   
print(f"元组支持索引: {tup[-2]}")   
print(f"元组支持切片:{tup[1:3]}")   
元组访问有序性: ('a', 'b', 'c')
元组支持索引: a
元组支持索引: b
元组支持切片:('b', 'c')

4.计算,长度,最大值,最小值,求和,排序

tup=(1,2,3,4,5)
#  元组相加
print(f"元组相加: {tup + (6, 7, 8)}")   
#  元组相乘
print(f"元组相乘: {tup * 2}")   
# 元组的成员运算
print(f"成员运算: {2 in tup}")   
# 元组的长度
print(f"元组的长度: {len(tup)}")   

#  最大值和最小值和求和
print(f"元组的最大值: {max(tup)}")  
print(f"元组的最小值: {min(tup)}")   
print(f"元组的求和: {sum(tup)}")  

#  排序
tup = tuple(sorted((5,3, 1, 4, 2)))
print(f"元组的排序: {tup}")   
元组相加: (1, 2, 3, 4, 5, 6, 7, 8)
元组相乘: (1, 2, 3, 4, 5, 1, 2, 3, 4, 5)
成员运算: True
元组的长度: 5
元组的最大值: 5
元组的最小值: 1
元组的求和: 15
元组的排序: (1, 2, 3, 4, 5)

3.3 遍历元组

1.使用for循环遍历元组

tup = (1, 2, 3, 4, 5)

for item in tup:
    print(f"遍历元组元素: {item}")  
遍历元组元素: 1
遍历元组元素: 2
遍历元组元素: 3
遍历元组元素: 4
遍历元组元素: 5

2.使用下标遍历元组

tup = (1, 2, 3, 4, 5)

for i in range(len(tup)):
    print(f"使用下标遍历元组元素: {tup[i]}")
使用下标遍历元组元素: 1
使用下标遍历元组元素: 2
使用下标遍历元组元素: 3
使用下标遍历元组元素: 4
使用下标遍历元组元素: 5

3.使用enumerate函数遍历元组

tup = (1, 2, 3, 4, 5)

for index, item in enumerate(tup):
    print(f"使用enumerate函数遍历元组元素: 索引 {index}, 元素 {item}")
使用enumerate函数遍历元组元素: 索引 0, 元素 1
使用enumerate函数遍历元组元素: 索引 1, 元素 2
使用enumerate函数遍历元组元素: 索引 2, 元素 3
使用enumerate函数遍历元组元素: 索引 3, 元素 4
使用enumerate函数遍历元组元素: 索引 4, 元素 5

4.将元组转换为列表遍历

tup = (1, 2, 3, 4, 5)

traverse_list = list(tup)
for item in traverse_list:
    print(f"将元组转换为列表遍历: {item}")
将元组转换为列表遍历: 1
将元组转换为列表遍历: 2
将元组转换为列表遍历: 3
将元组转换为列表遍历: 4
将元组转换为列表遍历: 5

5.使用生成器遍历元组

tup = (1, 2, 3, 4, 5)

for item in (x for x in tup):
    print(f"使用生成器遍历元组元素: {item}")
使用生成器遍历元组元素: 1
使用生成器遍历元组元素: 2
使用生成器遍历元组元素: 3
使用生成器遍历元组元素: 4
使用生成器遍历元组元素: 5

4.集合(Set)

set是一种无序,可变的数据类型,可包含任意类型,元素唯一不可重复,重复的元素将被自动去重,类似Java中的HashSet

set支持交集,并集,差集等集合操作

set不支持索引和切片

4.1 创建

常见创建

# 使用花括号创建集合
s = {1, 2, 3}

# 使用set()函数创建空集合
s = set()

# 可以包含任意类型
s = {1, "hello", 3.14, True}

s = {1, 2, 2, 3, 3, 3} #集合不允许重复元素,3会被自动去重

从字符串创建

s = set("hello")
print("使用set()函数接收字符串作为参数,创建集合:", s)
使用set()函数接收字符串作为参数,创建集合: {'h', 'o', 'e', 'l'}

从其他数据结构创建


#  使用set()函数接收列表创建集合
from_list=[1, 2, 3]
s = set(from_list)
print("使用set()函数接收列表参数,创建集合:", s)  

#  使用set()函数接收元组创建集合
from_tuple = (1, 2, 3)
s = set(from_tuple)
print("使用set()函数接收元组作为参数,创建集合:", s) 

# 使用set()函数接收字典创建集合
from_dict = {"a": 1, "b": 2}
s = set(from_dict)
print("使用set()函数接收字典作为参数,创建集合:", s)  

# 使用set()函数接收字典的values创建集合
s = set(from_dict.values())
print("使用set()函数接收字典的values作为参数,创建集合:", s) 

#  使用set()函数接收字典的items创建集合
s = set(from_dict.items())
print("使用set()函数接收字典的items作为参数,创建集合:", s) 



# 5) 使用set()函数接收集合创建集合
from_set = {1, 2, 3}
s = set(from_set)
print("使用set()函数接收集合作为参数,创建集合:", s)  

使用set()函数接收列表参数,创建集合: {1, 2, 3}
使用set()函数接收元组作为参数,创建集合: {1, 2, 3}
使用set()函数接收字典作为参数,创建集合: {'b', 'a'}
使用set()函数接收字典的values作为参数,创建集合: {1, 2}
使用set()函数接收字典的items作为参数,创建集合: {('a', 1), ('b', 2)}
使用set()函数接收集合作为参数,创建集合: {1, 2, 3}

从range函数创建

from_range = range(5)
s = set(from_range)   
print("使用set()函数接收range对象作为参数,创建集合:", s) 
使用set()函数接收range对象作为参数,创建集合: {0, 1, 2, 3, 4}

从推导式和生成器创建

#  使用set()函数接收生成器创建集合
from_generator = (x for x in range(5))
s = set(from_generator)   
print("使用set()函数接收生成器作为参数,创建集合:", s)   

#   使用集合推导式创建集合
s = {x for x in range(5)}   
print("使用集合推导式创建集合:", s)   
使用set()函数接收生成器作为参数,创建集合: {0, 1, 2, 3, 4}
使用集合推导式创建集合: {0, 1, 2, 3, 4}

带类型标识符创建


from typing import Set, Union

#  只包含字符串的集合
s1: Set[ Union[str, int, List[int] ] ] = {"z3", "li4", "w5", 8}

#  只包含字符串的集合
s2: Set[ str ] = {"z3", "li4", "w5"}

4.2 常见方法

1.增删改,长度,最值,求和,排序

s = {1, 2, 3, 4, 5}

#  集合添加元素
s.add(6)
print(f"集合添加元素: {s}")  


#   删除集合存在元素
s.remove(3)
print(f"集合删除元素: {s}")   

#  集合的成员检测
print(f"集合的成员检测: {4 in s}")   
print(f"集合的成员检测: {8 in s}")   


#  集合的长度
print(f"集合的长度: {len(s)}")   


#  集合的最大值和最小值和求和
print(f"集合的最大值: {max(s)}")  
print(f"集合的最小值: {min(s)}")   
print(f"集合的求和: {sum(s)}")  

#  集合的排序
sorted_set = sorted(s)
print(f"集合的排序: {sorted_set}")   

#  删除集合不存在元素
# s.remove(8)  # ❌ 会抛出 KeyError 异常
集合添加元素: {1, 2, 3, 4, 5, 6}
集合删除元素: {1, 2, 4, 5, 6}
集合的成员检测: True
集合的成员检测: False
集合的长度: 5
集合的最大值: 6
集合的最小值: 1
集合的求和: 18
集合的排序: [1, 2, 4, 5, 6]

2.交集并集差集

#  集合的交集
set_a = {1, 2, 3, 4, 5}
set_b = {4, 5, 6, 7, 8}

intersection_set = set_a.intersection(set_b)
print(f"集合的交集: {intersection_set}")   

#  集合的并集
union_set = set_a.union(set_b)
print(f"集合的并集: {union_set}")   

#  集合的差集
difference_set = set_a.difference(set_b)
print(f"集合的差集: {difference_set}")   
集合的交集: {4, 5}
集合的并集: {1, 2, 3, 4, 5, 6, 7, 8}
集合的差集: {1, 2, 3}

3.比较

  • == 左右集合元素相同
  • < 左是右的真子集
  • <= 左是右的子集
  • 子集 对于两个集合 ( A ) 和 ( B ),如果 ( A ) 中的每一个元素都是 ( B ) 中的元素,那么称 ( A ) 是 ( B ) 的子集
  • 真子集 如果 ( A ) 是 ( B ) 的子集,并且 ( A ≠ B )(即 ( A ) 至少比 ( B ) 少一个元素),那么称 ( A ) 是 ( B ) 的真子集
print( {1, 2, 3, 4, 5} == {1, 2, 3, 4, 5} ) # True 集合元素相同
print( {1, 2, 3, 4, 5} < {1, 2, 3, 4, 5} ) # False 不是真子集
print( {1, 2, 3, 4, 5} <= {1, 2, 3, 4, 5} ) # True 是子集
print( {1, 2, 3,  5} < {1, 2, 3, 4, 5} ) # True 是真子集

python集合的子集真子集比较,可用于权限标识比较

4.3 遍历

1.使用for循环遍历集合

set_a = {1, 2, 3, 4, 5}
for e in set_a:
    print(f"遍历集合元素: {e}") 
遍历集合元素: 1
遍历集合元素: 2
遍历集合元素: 3
遍历集合元素: 4
遍历集合元素: 5

2.enumerate遍历集合

for index, item in enumerate(set_a):
    print(f"使用enumerate遍历集合元素: {index} -> {item}") 
使用enumerate遍历集合元素: 0 -> 1
使用enumerate遍历集合元素: 1 -> 2
使用enumerate遍历集合元素: 2 -> 3
使用enumerate遍历集合元素: 3 -> 4
使用enumerate遍历集合元素: 4 -> 5

3.转换为list遍历

set不可直接像list那样for i in range(len(lst))下标遍历,因为没有顺序

set_list = list(set_a)  
for item in set_list:
    print(f"使用列表遍历集合元素: {item}")
使用列表遍历集合元素: 1
使用列表遍历集合元素: 2
使用列表遍历集合元素: 3
使用列表遍历集合元素: 4
使用列表遍历集合元素: 5

4.zip函数遍历

set_a = {1, 2, 3}
set_b = {4, 5, 6}
for item_a, item_b in zip(set_a, set_b):
    print(f"使用zip遍历多个集合元素: {item_a}, {item_b}")
使用zip遍历多个集合元素: 1, 4
使用zip遍历多个集合元素: 2, 5
使用zip遍历多个集合元素: 3, 6

5.字典(Dict)

待续

6.推导式 (Comprehension)

推导式是一种独特的数据处理方式,将一个可迭代对象(列表,元组,集合,字符串)的元素,通过某种条件运算或筛选后,构建成一个新的数据序列的结构体。类似Java中的Stream API。

Python支持各种数据结构的推导式。

6.1 列表推导式

大致形式:

[列表生成元素表达式 for 变量 in 列表]
[列表生成元素表达式 for 变量 in 列表 if 条件]

例💡:从list:lst中提取所有元素,通通扩大十倍

lst = [1,2,3,4,5,6,7,8,9,0]

sub_list = [s*10 for s in lst ]
print(sub_list) #[10, 20, 30, 40, 50, 60, 70, 80, 90, 0]

例💡:带条件的推导式,从list:lst中提取所有偶数,生成新的list:sub_list

lst = [1,2,3,4,5,6,7,8,9,0]

sub_list = [s for s in lst if s % 2 == 0 ]
print(sub_list) #[2, 4, 6, 8, 0]

例💡:提取所有偶数,并将它们乘以10

lst = [1,2,3,4,5,6,7,8,9,0]

sub_list = [s*10 for s in lst if s % 2 == 0 ]
print(sub_list) #[20, 40, 60, 80, 0]

例💡:0-4的5个数中,筛选出比2大的,对每个进行加3

lst = [x+3 for x in range(5) if x > 2]
print(lst) #[6, 7]

例💡:包含多个循环的列表推导式

continue1 = [1, 2, 3]
continue2 = ["a", "b", "c"]
lst = [(i, j) for i in continue1 for j in continue2]
print(lst) #[(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c'), (3, 'a'), (3, 'b'), (3, 'c')]

6.2 元组推导式

⚠️ 严格来讲没有元组推导式,元组推导式得到的是生成器对象

大致形式:
(列表生成元素表达式 for 变量 in 列表)
(列表生成元素表达式 for 变量 in 列表 if 条件)

例💡:根据列表,通过推导式生成一个元组

⚠️ 元组比较特殊,生成的对象是一个generator object生成器而不是元组本身,还需要tuple()函数转换为元组对象,且tuple()函数转换为元组对象前,不可对生成器对象进行迭代

lst = [1,2,3,4,5,6,7,8,9,0]

tup = (s*10 for s in lst if s % 2 == 0)
print( tup ) # <generator object <genexpr> at 0x000001CDE7A6BC60>
print( tuple(tup) ) # (20, 40, 60, 80, 0)

6.3 集合推导式

大致形式:
{列表生成元素表达式 for 变量 in 列表}
{列表生成元素表达式 for 变量 in 列表 if 条件}

例💡:提取偶数

lst = [1,2,3,4,5,6]

sub_list = {x for x in lst if x % 2 == 0}
print( sub_list) #{2, 4, 6}

6.4 字典推导式

大致形式:
{列表生成key元素表达式:列表生成value元素表达式 for 变量 in 列表}
{列表生成key元素表达式:列表生成value元素表达式 for 变量 in 列表 if 条件}

例💡:将列表中各字符串值为键,各字符串的长度为值,组成键值对

myList = ['Google','Oracle', 'Taobao','Baidu']

dic = {k:len(k) for k in myList}
print(dic) # {'Google': 6, 'Oracle': 6, 'Taobao': 6, 'Baidu': 5}

7.迭代器 (Iterator)

迭代器是访问集合元素的一种方式,是一个可以记住遍历位置的对象,从集合的第一个元素开始访问,直到所有元素被访问完结束,迭代器只会前进不能后退。

迭代器有两个基本方法iter()next()

字符串,列表或元组对象都可用于创建迭代器。

例💡:创建迭代器

iter(lst)就是创建了一个迭代器对象,通过next(it)不断获取下一个元素,如果获取到最后一个完成还要继续获取,则报错StopIteration(迭代器对象的一次性)

lst=[1,2,3,4]
it = iter(lst)    # 创建迭代器对象
print (next(it))   # 1
print (next(it))   # 2
print (next(it))   # 3
print (next(it))   # 4

print (next(it)) #❌ StopIteration

例💡:迭代器对象可以使用常规for语句进行遍历

tup=(1,2,3,4)
it = iter(tup)    
for e in it:
    print (e, end=" ")

例💡:迭代器对象的一次性使用,无论怎么遍历,已经遍历的不能复用

lst = [1,2,3,4,5,6,7,8,9,0]

it = iter(lst)

print(next(it))
print(next(it))

for e in it:
    print(f'for: ', e)
1
2
for:  3
for:  4
for:  5
for:  6
for:  7
for:  8
for:  9
for:  0

💡可迭代对象和迭代器的区别:

特性 可迭代对象 迭代器
定义 实现__iter__()方法的对象 实现__iter__()__next__()方法的对象
功能 可以被迭代 可记住迭代状态并产生下一个值
内存使用 更多 惰性计算,节省
数据消耗 可多次迭代 只能迭代一次
列表,元组,字典,字符串 文件对象,生成器

8.生成器 (Generator)

简单理解:生成器就是一个迭代器

1.生成器是一个返回迭代器的函数,使用yield关键字,只能用于迭代操作,可以利用它进行惰性计算,调用一个生成器函数,就会返回一个迭代器对象。

2.当生成器中使用yield关键字时,函数的执行将会暂停,并将yield后面的表达式当作当前迭代的值返回。

3.每次调用生成器的next方法或使用for循环进行迭代时,函数会从上次暂停的地方继续执行,再到再次遇到yield关键字,这样,生成器函数可以逐步产生值,不需要一次性计算并返回所有结果。

特点:

  • 惰性计算 只在需要时生成值
  • 内存高效 不一次性的存储所有数据
  • 一次性使用 遍历完成后就不能再次使用

例💡:

def countdown(n):
    while n > 0:
    #当在生成器函数中使用 yield 语句时,函数的执行将会暂停,并将 yield 后面的表达式作为当前迭代的值返回。
        yield n
        n = n - 1

# 创建生成器对象
generator = countdown(5)
print(type(generator)) # <class 'generator'> 生成器

# 通过迭代生成器获取值
print(next(generator))  # 输出: 5
print(next(generator))  # 输出: 4
print(next(generator))  # 输出: 3


# 使用 for 循环迭代生成器
for value in generator:
    print(value)  # 输出: 2 1
    
print(next(generator)) #❌ StopIteration

⚠️ 元组推导式只能得到生成器tup而不是元组tup,生成器误传进iter()进行迭代,返回的还是生成器tup本身

lst = [1,2,3,4,5,6,7,8,9,0]

tup = (s*10 for s in lst if s % 2 == 0)

it1 = iter(tup)
it2 = iter(tup)

print(id(tup))
print(id(it1))
print(id(it2))
1970972283424
1970972283424
1970972283424

生成器迭代后,不能再用tuple()生成元组

lst = [1,2,3,4,5,6,7,8,9,0]

tup = (s*10 for s in lst if s % 2 == 0)


print('迭代前', tuple(tup)) # 迭代前 (20, 40, 60, 80, 0)

for i in tup:
    print( f'for- ',i )

print('迭代后', tuple(tup)) # 迭代后 ()

💡生成器与推导式的区别:

特性 推导式 生成器
内存使用 立即计算,存储所有元素在内存 惰性运算,不占用内存存储元素
返回类型 返回集合,列表等具体类型,元组除外 生成器对象
执行时机 立即执行,返回所有结果 按需,next()
重用性 可多次使用 一次性,遍历后要重新构建
语法 [] {}等明确符号和 in for if组成表达式 yield函数
场景 数据量不大,需要立即得到结果 大量数据,内存敏感,只需遍历一次

内存占用对比:

生成器对象比推导式得到的具体数据结构对象节省内存的多

import sys

COUNT = 10000

large_list = [x for x in range(100 * COUNT)]
print("列表内存占用:", sys.getsizeof(large_list), "bytes")  # 8448728 bytes

large_tup = (x for x in range(100 * COUNT))
print("生成器内存占用:", sys.getsizeof(large_tup), "bytes")  # 192 bytes

执行时机对比:

推导式,整个计算,得到新的列表对象,立即执行,容易瞬间打满CPU/内存

def expensive_operation(x):
    print(f"计算 {x} 的平方...")
    return x * x


squares_list = [expensive_operation(x) for x in range(10)]
print(squares_list)
计算 0 的平方...
计算 1 的平方...
计算 2 的平方...
计算 3 的平方...
计算 4 的平方...
计算 5 的平方...
计算 6 的平方...
计算 7 的平方...
计算 8 的平方...
计算 9 的平方...
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

生成器对象,数据结构并没有实际生成每个成员,只有迭代时用到才产生,惰性执行

squares_gen = (expensive_operation(x) for x in range(10))
print('生成器对象初始化完成')

print(next(squares_gen))
print(next(squares_gen))
print(next(squares_gen))

for result in squares_gen:
    print("for -----> ", result)
生成器对象初始化完成
计算 0 的平方...
0
计算 1 的平方...
1
计算 2 的平方...
4
计算 3 的平方...
for ----->  9
计算 4 的平方...
for ----->  16
计算 5 的平方...
for ----->  25
计算 6 的平方...
for ----->  36
计算 7 的平方...
for ----->  49
计算 8 的平方...
for ----->  64
计算 9 的平方...
for ----->  81

在需要高性能程序时,需要考虑使用生成器优化程序


"如果文章对您有帮助,可以请作者喝杯咖啡吗?"

微信二维码

微信支付

支付宝二维码

支付宝


Python的数据结构,推导式、迭代器和生成器
https://blog.liuzijian.com/post/python/2026/01/01/python-data-structure/
作者
Liu Zijian
发布于
2026年1月1日
更新于
2026年5月4日
许可协议