惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
U
Unit 42
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
J
Java Code Geeks
D
DataBreaches.Net
B
Blog RSS Feed
D
Docker
L
LangChain Blog
aimingoo的专栏
aimingoo的专栏
F
Fortinet All Blogs
Y
Y Combinator Blog
A
About on SuperTechFans
V
V2EX
罗磊的独立博客
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
MongoDB | Blog
MongoDB | Blog
博客园 - 【当耐特】
Last Week in AI
Last Week in AI
S
SegmentFault 最新的问题
月光博客
月光博客
Vercel News
Vercel News
H
Hackread – Cybersecurity News, Data Breaches, AI and More
阮一峰的网络日志
阮一峰的网络日志

Liu Zijian's Blog | 一个技术博客

使用Certbot自动续签HTTPS证书 使用Filebeat采集Nginx日志到ES Python的协程 Python中的异常 Python中的类和对象 Python的函数 Spring AI集成多模态模型 LangChain4j多模态 LangChain Tools工具使用 Python中的模块和包 Python全局环境和虚拟环境(venv) LangChain Prompt提示词工程 LangChain4j Tools工具使用 基于Dify搭建AI智能体应用 LangChain4j RAG检索增强生成 Spring AI实现MCP Server Spring AI集成MCP Client LangChain4j Prompt提示词工程 Spring AI使用知识库增强对话功能 Spring AI实现一个智能客服 Spring AI实现一个简单的对话机器人 实现MinIO数据的每日备份 自己实现一个DNS服务 简单理解AI智能体 大模型和大模型应用 LangChain开篇 LangChain4j开篇 一个解析Excel2007的POI工具类 DataPermissionInterceptor源码解读 TenantLineInnerInterceptor源码解读
Python的数据结构,推导式、迭代器和生成器
Liu Zijian · 2026-01-01 · via Liu Zijian's Blog | 一个技术博客

未完待续

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

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函数同时遍历多个列表

内置的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)

字典(Dict)是一种由键值对组成的,有序的可变的数据类型

  • Python3.7以后,字典是有序的,保持插入顺序。
  • 字典由键值对组成,键必须是不可变类型(如字符串、数字、元组)不能是(列表、集合、字典等)可变类型,值可以是任意类型。值可以重复,键必须唯一,如果键重复,新的值会覆盖前面旧的值。
  • 字典是可变的,可以添加、修改或删除键值对。
  • 字典没有索引,不能用下标或切片访问。

5.1 创建

花括号{}创建字典

dic = {"a": 1, "b": 2, "c": 3}
print(dic) #有序的
print(dic.items()) # 键值对
print(dic.keys()) # 键
print(dic.values()) # 值
{'a': 1, 'b': 2, 'c': 3}
dict_items([('a', 1), ('b', 2), ('c', 3)])
dict_keys(['a', 'b', 'c'])
dict_values([1, 2, 3])

通过键访问

dic = {'a': 1, 'b': 2, 'c': 3}

print( dic['a'] ) #1
print( dic.get('a') ) #1

可变

dic = {'a': 1, 'b': 2, 'c': 3}

dic.update({'c': 5, 'd': 4})

print(dic) #{'a': 1, 'b': 2, 'c': 5, 'd': 4}

使用dict()函数接收键值对创建字典

dic = dict()
print("使用dict()函数创建空字典:", dic)  # {}

dic = dict(name="name", age=20)
print( dic) #{'name': 'name', 'age': 20}

dic = dict([("name", "qq"), ("age", 25)])
print( dic) #{'name': 'qq', 'age': 25}

使用dict()函数从其他数据结构创建字典


# 使用dict()函数接收列表创建字典
from_list = [("a", 1), ("b", 2), ("c", 3)]
dic = dict(from_list)
print(dic)  # {'a': 1, 'b': 2, 'c': 3}

# 使用dict()函数接收元组创建字典
from_tuple = (("a", 1), ("b", 2), ("c", 3))
dic = dict(from_tuple)
print(dic)  # {'a': 1, 'b': 2, 'c': 3}
# 使用dict()函数接收集合创建字典
from_set = {("a", 1), ("b", 2), ("c", 3)}
dic = dict(from_set)
print(dic)  # {'c': 3, 'a': 1, 'b': 2}

# 使用dict()函数接收字典创建字典
from_dict = {"a": 1, "b": 2, "c": 3}
dic = dict(from_dict)
print(dic)  # {'a': 1, 'b': 2, 'c': 3}

使用zip()函数创建字典

keys = "abc"
values = [1, 2, 3]
print( dict(zip(keys, values)) ) # {'a': 1, 'b': 2, 'c': 3}
keys = ['a', 'b', 'c']
values = [1, 2, 3]
print( dict(zip(keys, values)) ) # {'a': 1, 'b': 2, 'c': 3}
keys = "abc"
from_range = range(3)
dic = dict(zip(keys, from_range)) 
print(dic)  # {'a': 0, 'b': 1, 'c': 2}

5.2 常见方法

添加新的键值对

dic = {'a': 1, 'b': 2, 'c': 3}

dic['d'] = 4

print(dic) #{'a': 1, 'b': 2, 'c': 3, 'd': 4}

修改键对应的值

dic = {'a': 1, 'b': 2, 'c': 3}

dic['c'] = 40

print(dic) #{'a': 1, 'b': 2, 'c': 40}

删除某个键值对

dic = {'a': 1, 'b': 2, 'c': 3}

e = dic.pop('c')

print(e) #3
print(dic) #{'a': 1, 'b': 2}

删除的键找不到,返回指定的默认值

dic = {'a': 1, 'b': 2, 'c': 3}

e = dic.pop('d', 0)

print(e) #0

print(dic) # {'a': 1, 'b': 2, 'c': 3}

通过del删除

dic = {'a': 1, 'b': 2, 'c': 3}

del dic['c']

print(dic) #{'a': 1, 'b': 2}

pop()能返回删除的键值对的值,但是del不能

成员key存在检测

dic = {'a': 1, 'b': 2, 'c': 3}

print('a' in dic) #True

print('f' in dic) #False

字典长度

dic = {'a': 1, 'b': 2, 'c': 3}

print("获取字典长度:", len(dic))  # 3

最大最小,根据key首字符unicode码值,如相同再去比较下一位字符

dic = {"name": "z3", "age": 18, "gender": "男"}
print("字典中最大值查找:", max(dic))  # name
print("字典中最小值查找:", min(dic))  # age

排序

dic = {"pink": 14, "red": 2, "zoo": 73, 'blue': 4}

print('原字典', dic)

sorted_dict_key = sorted(dic)

print("字典的键排序:", sorted_dict_key)

sorted_dict_value = sorted(dic.items(), key=lambda item: item[1]) #从每个entry中取出第二个([1])即为value

print("字典的值排序:", sorted_dict_value)
原字典 {'pink': 14, 'red': 2, 'zoo': 73, 'blue': 4}
字典的键排序: ['blue', 'pink', 'red', 'zoo']
字典的值排序: [('red', 2), ('blue', 4), ('pink', 14), ('zoo', 73)]

默认值,get()setdefault()都可实现取值时设置默认值

dic = {"a": 1, "b": 2, "c": 3}
print(  dic.get("a", "没有找到") )  # 1
print(  dic.get("f", "没有找到") )  # 没有找到

print(  dic.setdefault("a", "没有找到") )  # 1
print(  dic.setdefault("f", "没有找到") )  # 没有找到

合并,如果没有key相同,则update()能用于将字典合并

dict1 = {"name": "🐔哥", "age": 25, "gender": "男"}
dict2 = {"hobby": "打篮球", "clouth": '背带裤'}
dict2.update(dict1)
print(  dict2 ) #{'hobby': '打篮球', 'clouth': '背带裤', 'name': '🐔哥', 'age': 25, 'gender': '男'}

5.3 遍历

遍历字典的键,值,键值对

dic = {"a": 1, "b": 2, "c": 3, 'd': 4}

for key in dic:
    print(f"遍历字典的键: {key}") 

for value in dic.values():
    print(f"遍历字典的值: {value}")  

for key, value in dic.items():
    print(f"遍历字典的键值对: 键 {key}, 值 {value}")  

for item in dic.items():
    print(f"遍历字典的键值对:{item}")  
遍历字典的键: a
遍历字典的键: b
遍历字典的键: c
遍历字典的键: d
遍历字典的值: 1
遍历字典的值: 2
遍历字典的值: 3
遍历字典的值: 4
遍历字典的键值对: 键 a, 值 1
遍历字典的键值对: 键 b, 值 2
遍历字典的键值对: 键 c, 值 3
遍历字典的键值对: 键 d, 值 4
遍历字典的键值对:('a', 1)
遍历字典的键值对:('b', 2)
遍历字典的键值对:('c', 3)
遍历字典的键值对:('d', 4)

enumerate()带顺序遍历

dic = {"a": 1, "b": 2, "c": 3, 'd': 4}

for index, item in enumerate(dic.items()):
    print(f"使用enumerate函数遍历字典: 索引 {index}, 键值对:{item}")  
    
for index, (key, value) in enumerate(dic.items()):
    print(f"使用enumerate函数遍历字典: 索引 {index}, 键 {key}, 值 {value}") 
使用enumerate函数遍历字典: 索引 0, 键值对:('a', 1)
使用enumerate函数遍历字典: 索引 1, 键值对:('b', 2)
使用enumerate函数遍历字典: 索引 2, 键值对:('c', 3)
使用enumerate函数遍历字典: 索引 3, 键值对:('d', 4)
使用enumerate函数遍历字典: 索引 0, 键 a, 值 1
使用enumerate函数遍历字典: 索引 1, 键 b, 值 2
使用enumerate函数遍历字典: 索引 2, 键 c, 值 3
使用enumerate函数遍历字典: 索引 3, 键 d, 值 4

转换为列表后,进行遍历

dic = {"a": 1, "b": 2, "c": 3, 'd': 4}

dict_list = list(dic.items())  # 转换为有序列表
for item in dict_list:
    print(f"转换为列表后遍历字典: 键值对 {item}")  
    
for key, value in dict_list:
    print(f"转换为列表后遍历字典: , 键 {key}, 值 {value}")  
转换为列表后遍历字典: 键值对 ('a', 1)
转换为列表后遍历字典: 键值对 ('b', 2)
转换为列表后遍历字典: 键值对 ('c', 3)
转换为列表后遍历字典: 键值对 ('d', 4)
转换为列表后遍历字典: , 键 a, 值 1
转换为列表后遍历字典: , 键 b, 值 2
转换为列表后遍历字典: , 键 c, 值 3
转换为列表后遍历字典: , 键 d, 值 4

使用生成器遍历字典,不允许在for前面直接解包key, value

dic = {"a": 1, "b": 2, "c": 3, 'd': 4}

dict_generator = (item for item in dic.items())
for item in dict_generator:
    print(f"使用生成器遍历字典: 键值对:{item}")
使用生成器遍历字典: 键值对:('a', 1)
使用生成器遍历字典: 键值对:('b', 2)
使用生成器遍历字典: 键值对:('c', 3)
使用生成器遍历字典: 键值对:('d', 4)
dic = {"a": 1, "b": 2, "c": 3, 'd': 4}

dict_generator = (item for item in dic.items())

for k, v in dict_generator:
    print(f"使用生成器遍历字典: 键值对:{k} = {v}")
使用生成器遍历字典: 键值对:a = 1
使用生成器遍历字典: 键值对:b = 2
使用生成器遍历字典: 键值对:c = 3
使用生成器遍历字典: 键值对:d = 4

使用zip()函数遍历多个字典

dict_a = {"name": "z3", "age": 18}
dict_b = {"city": "北京", "hobby": "打篮球"}

for item_a, item_b in zip(dict_a.items(), dict_b.items()):
    print(f"使用zip函数遍历多个字典: 键值={item_a} | 键值={item_b}")

for (key_a, value_a), (key_b, value_b) in zip(dict_a.items(), dict_b.items()):
    print(f"使用zip函数遍历多个字典: 键 {key_a}, 值 {value_a} | 键 {key_b}, 值 {value_b}")

for a, b in zip(dict_a, dict_b):
    print(f"a={a},b={b}")
使用zip函数遍历多个字典: 键值=('name', 'z3') | 键值=('city', '北京')
使用zip函数遍历多个字典: 键值=('age', 18) | 键值=('hobby', '打篮球')
使用zip函数遍历多个字典: 键 name, 值 z3 | 键 city, 值 北京
使用zip函数遍历多个字典: 键 age, 值 18 | 键 hobby, 值 打篮球
a=name,b=city
a=age,b=hobby

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}

字典推导式遍历字典

dic = {"a": 1, "b": 2, "c": 3, 'd': 4}

dict_comprehension = {key: value for key, value in dic.items()}
for item in dict_comprehension.items():
    print(f"使用字典推导式遍历字典: 键值对:{item}")
for key,value in dict_comprehension.items():
    print(f"使用字典推导式遍历字典: 键 {key}, 值 {value}")
使用字典推导式遍历字典: 键值对:('a', 1)
使用字典推导式遍历字典: 键值对:('b', 2)
使用字典推导式遍历字典: 键值对:('c', 3)
使用字典推导式遍历字典: 键值对:('d', 4)
使用字典推导式遍历字典: 键 a, 值 1
使用字典推导式遍历字典: 键 b, 值 2
使用字典推导式遍历字典: 键 c, 值 3
使用字典推导式遍历字典: 键 d, 值 4

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

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