本专栏系列为Pythong基础系列,每篇内容非常全面,包含全网各个知识点,非常长,请耐心看完。
每天都会更新新的内容,搜罗全网资源以及自己在学习和工作过程中的一些总结,可以说是非常详细和全面。
以至于为什么要写的这么详细:自己也是学过Python的,很多新手只是简单的过一篇语法,其实对于一个知识点的底层逻辑和其他使用方法以及参数详情根本不是很了解,这就导致学完很容易忘记,而且在实战过程中也是半知半解,所以自己就尽量写的详细些,让需要的人能更了解Python的每一个知识点,也感谢大家指正,祝大家早日从小码农变成大牛!
编程不仅是技术的堆砌,更是灵魂的创造,每一次代码的跳动,都是向世界宣告你的不凡!
- 博客主页:长风清留扬-CSDN博客
- 系列专栏:Python基础专栏
- 每天更新大数据相关方面的技术,分享自己的实战工作经验和学习总结,尽量帮助大家解决更多问题和学习更多新知识,欢迎评论区分享自己的看法
- 感谢大家点赞👍收藏⭐评论
知识点与思维导图整理
Python元组
Python中的元组(Tuple)是一种用于存储多个项目的数据结构,但它与列表(List)不同,主要区别在于元组的元素是不可变的,即一旦创建,就不能更改其内部元素的值。元组使用圆括号
() 来定义,元素之间用逗号 , 分隔。
元组的特性
1、不可变性(Immutability)
- 特性描述:元组的最大特性是其不可变性。一旦元组被创建,你就不能更改其内部元素的值。这种不可变性使得元组在某些场景下比列表(List)更加安全和高效,特别是在需要保证数据不被意外修改时。
示例:
my_tuple = (1, 2, 3)
# 尝试修改元组中的元素将引发TypeError
# my_tuple[0] = 4 # 这会抛出TypeError
有序性(Ordering)
- 特性描述:元组中的元素是有序的,即元素在元组中的位置是固定的。你可以通过索引来访问元组中的特定元素。
示例:
my_tuple = ('a', 'b', 'c')
print(my_tuple[1]) # 输出: b
可迭代性(Iterability)
- 特性描述:元组是可迭代的,这意味着你可以使用循环(如for循环)来遍历元组中的每个元素。
示例:
my_tuple = (1, 2, 3, 4, 5)
for item in my_tuple:
print(item)
可包含不同类型元素(Heterogeneity)
- 特性描述:元组可以包含不同类型的元素,包括整数、浮点数、字符串、列表(尽管列表是可变的,但可以作为元素存储在元组中)、其他元组等。
示例:
my_tuple = (1, 'a', 3.14, [4, 5, 6])
可作为字典的键(Hashable)
- 特性描述:由于元组的不可变性,它可以作为字典(Dictionary)的键。这是列表无法做到的,因为列表是可变的。
示例:
my_dict = {(1, 2): 'a', (3, 4): 'b'}
print(my_dict[(1, 2)]) # 输出: a
支持切片(Slicing)
- 特性描述:元组支持切片操作,允许你获取元组的一个子序列。
示例:
my_tuple = (1, 2, 3, 4, 5)
print(my_tuple[1:3]) # 输出: (2, 3)
支持连接(Concatenation)和重复(Repetition)
- 特性描述:元组支持使用+操作符进行连接,以及使用*操作符进行重复。
示例:
tuple1 = (1, 2, 3)
tuple2 = (4, 5, 6)
print(tuple1 + tuple2) # 输出: (1, 2, 3, 4, 5, 6)
print(tuple1 * 2) # 输出: (1, 2, 3, 1, 2, 3)
元组的应用场景
函数参数和返回值
- 函数参数:元组可以作为函数的参数传递,这样可以方便地传递多个相关值。使用元组作为参数,可以使函数的定义更加简洁,同时避免在调用函数时传递过多的独立参数。
- 函数返回值:函数可以返回一个元组,从而实现一次性返回多个值的效果。这比使用多个返回值(虽然Python支持通过解包来接收多个返回值,但本质上仍然是返回一个元组)更加直观和方便。
字典的键
由于元组是不可变的,因此它可以作为字典(Dictionary)的键。这在需要使用多个值作为键的情况下非常有用,因为列表等可变类型不能作为字典的键。
数据记录和表示
- 记录数据:元组可以用于表示具有多个字段的记录,如一个坐标点(x, y)、一个学生的姓名和年龄等。元组的有序性和不可变性使得它成为表示这类数据的理想选择。
- 固定集合:元组可以用作一组不可变的元素,类似于集合(Set),但具有顺序。这使得元组在需要保持元素顺序不变的场景中非常有用。
数据安全性和保护
- 防止数据被修改:如果有一组数据在整个程序中都不应该被修改,使用元组可以提供保护。由于元组的不可变性,一旦数据被封装在元组中,就无法再被修改,从而保证了数据的安全性。
- 多线程安全:在多线程编程中,共享数据的修改可能导致竞态条件(Race Condition)。使用元组作为共享数据的一种形式,可以避免这种情况的发生,因为元组是不可变的。
字符串格式化
元组经常用于字符串格式化,将变量插入字符串中。通过使用str.format()方法或f-string(Python 3.6+),可以将元组中的元素格式化为字符串的一部分。
解包操作
元组支持解包操作,即可以将元组中的值分配给多个变量。这种操作在接收函数返回的多个值或处理具有多个字段的数据记录时非常有用。
嵌套和组合
- 嵌套元组:元组可以嵌套在其他元组中,从而创建更复杂的数据结构。这种嵌套结构可以表示具有层次关系的数据。
- 与其他数据结构组合:元组也可以与其他数据结构(如列表、字典等)组合使用,以创建更加灵活和强大的数据结构。
性能优势
- 内存占用小:与列表相比,元组在内存占用上通常更小。这是因为元组是不可变的,Python可以在创建元组时对其内部元素进行优化存储。
- 访问速度快:由于元组的有序性和不可变性,Python可以对其进行优化以提高访问速度。这使得元组在处理大量数据时非常高效。
元组为什么没有增删改
Python 中的元组(Tuple)是一种内置的数据结构,用于存储有序的元素集合。与列表(List)相似,元组也是序列类型的一种,但它们在几个关键方面有所不同,最显著的区别之一就是元组是不可变的(immutable)。这意味着一旦元组被创建,你就不能增加、删除或修改其中的元素。这种设计决策背后有几个原因:
- 保证数据安全性:
不可变性是数据安全的一个重要特性。在需要保护数据不被意外修改的场景中,元组非常有用。例如,你可以将元组用作字典的键(keys),因为字典的键必须是不可变的。如果元组是可变的,那么用作键的元组在字典创建后可能会被修改,这将导致字典的行为变得不可预测。 - 提高性能:
由于元组是不可变的,Python 可以在内部对元组进行更多的优化。例如,Python 可以在创建元组时计算出其哈希值,并在后续操作中直接使用这个哈希值,而无需重新计算。相比之下,对于可变的数据结构(如列表),由于内容可能会改变,每次使用时都需要重新计算哈希值,这会影响性能。 - 简化设计:
在Python的设计哲学中,简单性和明确性是非常重要的。为元组提供增删改功能将使其与列表更加相似,从而模糊了两者之间的界限。通过将元组设计为不可变类型,Python的开发者们强调了它们之间的区别,并鼓励开发者根据数据的可变性需求来选择合适的数据结构。 - 内存效率:
由于元组是不可变的,Python 可以在某些情况下对元组进行内存优化,比如通过共享相同内容的元组实例来减少内存使用。这种优化在大量使用元组的程序中可能会带来显著的性能提升。
为什么要把元组设置成不可变序列
Python中的元组(Tuple)被设计成不可变序列,这一设计决策背后有多重原因,这些原因不仅关乎Python语言本身的特性和哲学,还涉及到编程实践中的多个方面。
- 数据安全性:
不可变性是保护数据不被意外修改的一种有效手段。在需要确保数据在创建后不会改变的场景中,元组提供了这样的保证。例如,在函数返回多个值时,使用元组可以避免外部代码对这些值进行不必要的修改,从而保证了数据的完整性和安全性。 - 作为字典的键:
在Python中,字典(Dictionary)的键(Key)必须是不可变的。这是因为字典内部通过哈希表来实现快速查找,而哈希表的实现依赖于键的不可变性。如果键是可变的,那么其哈希值可能会在字典的生命周期内发生变化,这将导致字典无法正确地定位键值对,从而破坏字典的完整性和性能。元组作为不可变序列,自然成为了字典键的理想选择。 - 简化内存管理:
由于元组是不可变的,Python解释器可以对其内存管理进行优化。例如,当多个变量引用同一个元组时,它们实际上是指向同一个内存地址的,因为元组的内容不会改变。这种共享机制可以减少内存的使用,并提高程序的效率。相比之下,如果元组是可变的,那么每次修改都需要复制整个元组,这将大大增加内存的开销。 - 避免复杂的错误:
在编程中,可变数据结构往往更容易引发错误。例如,在多线程或多进程环境中,对可变数据结构的并发访问可能会导致竞态条件(Race Condition)和数据不一致的问题。而元组作为不可变序列,自然避免了这些问题。此外,由于元组的内容不会改变,因此在使用元组时,程序员可以更加自信地假设其值在程序的执行过程中是稳定的。 - 符合Python的设计哲学:
Python的设计哲学之一是“用一种方法,最好是只有一种方法来做一件事”(There should be one-- and preferably only one --obvious way to do it)。通过将元组设计为不可变序列,Python强调了与列表(List)这一可变序列的区别,并鼓励程序员根据数据的可变性需求来选择合适的数据结构。这种设计哲学有助于保持Python代码的清晰性和一致性。
元组创建语法
基本创建语法
元组的基本创建语法是通过将元素放在圆括号()中,元素之间用逗号,
my_tuple = (1, 2, 3)
print(my_tuple) # 输出: (1, 2, 3)
如果元组中只有一个元素,并且希望它被视为一个元组而不是该元素的普通表示,则需要在元素后面加上逗号,
singleton_tuple = (1,)
print(type(singleton_tuple)) # 输出: <class 'tuple'>
使用tuple()函数
tuple()函数可以将任何可迭代对象(如列表、字符串、集合等)转换为元组。这对于需要将其他类型的序列或集合转换为元组时非常有用:
my_list = [1, 2, 3]
my_tuple = tuple(my_list)
print(my_tuple) # 输出: (1, 2, 3)
my_string = 'hello'
my_char_tuple = tuple(my_string)
print(my_char_tuple) # 输出: ('h', 'e', 'l', 'l', 'o')
嵌套元组
元组可以嵌套在另一个元组中,以创建更复杂的数据结构。嵌套元组在表示具有层次关系的数据时非常有用:
nested_tuple = (1, (2, 3), 4)
print(nested_tuple) # 输出: (1, (2, 3), 4)
# 访问嵌套元组的元素
print(nested_tuple[1]) # 输出: (2, 3)
print(nested_tuple[1][0]) # 输出: 2
使用字面量(直接赋值)
元组也可以通过直接赋值给变量的方式来创建,这在很多情况下是最简单和最直接的方法:
empty_tuple = ()
singleton_tuple = (1,)
multi_element_tuple = (1, 2, 3, 'a', 'b', 'c')
解包与元组
虽然这不是元组创建的直接语法,但了解如何在创建元组时使用解包操作是很重要的。解包允许你将可迭代对象(如列表、另一个元组等)的元素直接分配给元组的元素:
elements = [1, 2, 3]
my_tuple = tuple(elements) # 使用tuple()函数转换
# 或者使用解包(但注意,这里实际上是在赋值时使用了元组字面量)
# 假设你已经有了一个列表或另一个可迭代对象
*elements, = [1, 2, 3] # 这是扩展的可迭代解包,但在创建元组时通常不这么用
my_tuple = (*elements,) # 注意逗号,使其成为一个元组
print(my_tuple) # 输出: (1, 2, 3)
使用元组推导式(Python 3.x)
虽然元组本身是不可变的,但你可以使用元组推导式(类似于列表推导式)来从一个可迭代对象(如列表、集合等)中创建元组。不过,需要注意的是,元组推导式的结果需要被显式地放在圆括号中以创建一个元组:
关于元组的推导式推荐阅读:
从菜鸟到高手:掌握Python推导式,让代码飞起来,列表、集合、字典,一网打尽,用Python推导式优雅地重构你的数据操作
numbers = [1, 2, 3, 4, 5]
squared_tuple = tuple(x**2 for x in numbers)
print(squared_tuple) # 输出: (1, 4, 9, 16, 25)
# 注意:这里的tuple()函数用于将推导式的结果转换为元组
# 如果只是简单地写 (x**2 for x in numbers) 而不加tuple(),则得到一个生成器表达式
总结
元组的创建语法主要通过圆括号()、逗号,以及可选的tuple()函数来实现。
元组的遍历
使用for循环遍历元组
# 定义一个元组
my_tuple = (1, 'Hello', 3.14, True)
# 使用for循环遍历元组
for item in my_tuple:
print(item) # 打印每个元素
# 输出结果
# 1
# Hello
# 3.14
# True
使用enumerate()函数遍历元组
enumerate()函数将元组(或任何可迭代对象)组合为一个索引序列,同时列出数据和数据下标,常用于在for循环中获取每个元素的索引和值。
关于enumerate()的使用,推荐阅读:
Python中你不知道的迭代神器! 解锁Python的枚举魔法:enumerate函数深度剖析,告别手动计数,让Python循环与索引共舞
# 定义一个元组
my_tuple = (1, 'Hello', 3.14, True)
# 使用enumerate()遍历元组
for index, item in enumerate(my_tuple):
print(f"Index: {index}, Item: {item}")
# 输出结果
# Index: 0, Item: 1
# Index: 1, Item: Hello
# Index: 2, Item: 3.14
# Index: 3, Item: True
使用zip()函数遍历元组(通常与另一个可迭代对象一起使用)
虽然zip()函数主要用于将多个可迭代对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的zip对象(可以使用list()来转换为列表),但它也可以与单个元组一起使用(但通常不是遍历元组的首选方法,因为单独使用时没有特别的遍历优势)。
# 定义一个元组和另一个列表
my_tuple = (1, 'Hello', 3.14, True)
another_list = ['a', 'b', 'c', 'd']
# 使用zip()遍历两个可迭代对象(这里仅作为示例,单独遍历元组时不常用)
for t, l in zip(my_tuple, another_list):
print(f"Tuple Item: {t}, List Item: {l}")
# 输出结果
# Tuple Item: 1, List Item: a
# Tuple Item: Hello, List Item: b
# Tuple Item: 3.14, List Item: c
# Tuple Item: True, List Item: d
使用列表推导式遍历元组(生成新列表)
虽然列表推导式主要用于生成列表,但你也可以通过它遍历元组并根据条件生成新的列表(或元组,但需要使用元组推导式)。
关于元组的推导式推荐阅读:
从菜鸟到高手:掌握Python推导式,让代码飞起来,列表、集合、字典,一网打尽,用Python推导式优雅地重构你的数据操作
# 定义一个元组
my_tuple = (1, 2, 3, 4, 5)
# 使用列表推导式遍历元组,并生成一个新列表,包含原元组中每个元素的平方
squared_list = [item**2 for item in my_tuple]
print(squared_list)
# 输出结果
# [1, 4, 9, 16, 25]
# 注意:如果你想要生成新的元组而不是列表,应该使用元组推导式(Python 3.6+支持)
squared_tuple = tuple(item**2 for item in my_tuple)
print(squared_tuple)
# 输出结果
# (1, 4, 9, 16, 25)
元组的数学运算
在Python中,元组(Tuple)是不可变序列类型,这意呀着一旦元组被创建,你就不能更改其内部的元素。但是,元组支持一些特殊的运算,包括使用+操作符进行元组合并(concatenation)和使用*操作符进行元组重复(repetition)。
元组合并(使用+操作符)
tuple1和tuple2是两个独立的元组。使用+操作符将它们合并成一个新的元组merged_tuple,其中包含了tuple1和tuple2中所有的元素。
# 定义两个元组
tuple1 = (1, 2, 3)
tuple2 = (4, 5, 6)
# 使用+操作符合并两个元组
merged_tuple = tuple1 + tuple2
# 打印合并后的元组
print("合并后的元组:", merged_tuple) # 运行结果:合并后的元组: (1, 2, 3, 4, 5, 6)
元组重复(使用*操作符)
tuple3是一个包含三个元素的元组。使用*操作符并指定数字3,我们将tuple3重复了三次,得到了一个新的元组repeated_tuple,它包含了原元组三个副本中的所有元素。
# 定义一个元组
tuple3 = (7, 8, 9)
# 使用*操作符重复元组三次
repeated_tuple = tuple3 * 3
# 打印重复后的元组
print("重复后的元组:", repeated_tuple) # 运行结果:重复后的元组: (7, 8, 9, 7, 8, 9, 7, 8, 9)
总结
- 元组支持使用+操作符进行合并,即将两个或多个元组中的元素组合成一个新的元组。
- 元组还支持使用*操作符进行重复,即创建一个新的元组,其中包含指定次数的原元组的副本。
元组的函数操作
函数/操作符的作用 | 函数/操作符 | 函数的描述/操作符的用法 |
---|---|---|
获取元组长度 | len() | 返回元组中元素的数量。 |
获取元组中的最大值 | max() | 返回元组中所有元素的最大值(元素必须可比较)。如果元组为空,将引发ValueError 。 |
获取元组中的最小值 | min() | 返回元组中所有元素的最小值(元素必须可比较)。如果元组为空,将引发ValueError 。 |
计算元组中元素的总和 | sum() | 返回元组中所有元素的总和。如果元组为空,返回0。可以指定一个可选的起始值进行累加。 |
检查元组中所有元素是否为真 | all() | 如果元组中的所有元素都为真(即非零、非空、非None等),则返回True;否则返回False。空元组被视为True,因为没有元素为假。 |
检查元组中是否存在至少一个真元素 | any() | 如果元组中至少有一个元素为真,则返回True;否则返回False。空元组被视为False,因为没有元素为真。 |
检查元素是否存在于元组中 | in | 如果指定的元素在元组中出现,则返回True;否则返回False。 |
检查元素是否不在元组中 | not in | 如果指定的元素不在元组中出现,则返回True;否则返回False。 |
len() 函数
len() 函数用于获取容器(如列表、元组、字符串等)中元素的数量。
# 定义一个列表
my_list = [1, 2, 3, 4, 5]
# 使用len()函数获取列表的长度
list_length = len(my_list)
# 打印结果
print("列表的长度是:", list_length) # 输出结果:列表的长度是: 5
max() 函数
max() 函数返回给定参数(或可迭代对象)中的最大值。如果参数是一个可迭代对象,max() 会返回该对象中最大的元素。
# 定义一个列表
numbers = [1, 3, 5, 7, 9]
# 使用max()函数获取列表中的最大值
max_number = max(numbers)
# 打印结果
print("列表中的最大值是:", max_number) # 输出结果:列表中的最大值是: 9
# 也可以直接使用多个参数
print("三个数中的最大值是:", max(1, 3, 5)) # 输出结果:三个数中的最大值是: 5
min() 函数
min() 函数与 max() 函数相反,它返回给定参数(或可迭代对象)中的最小值。
# 定义一个列表
numbers = [2, 4, 6, 8, 10]
# 使用min()函数获取列表中的最小值
min_number = min(numbers)
# 打印结果
print("列表中的最小值是:", min_number) # 输出结果:列表中的最小值是: 2
# 也可以直接使用多个参数
print("三个数中的最小值是:", min(3, 1, 2)) # 输出结果:三个数中的最小值是: 1
sum() 函数
sum() 函数用于计算可迭代对象(如列表、元组、集合)中所有元素的总和,也可以指定一个起始值进行累加。
# 定义一个列表
numbers = [1, 2, 3, 4, 5]
# 使用sum()函数计算列表元素的总和
total = sum(numbers)
# 打印结果
print("列表元素的总和是:", total) # 输出结果:列表元素的总和是: 15
# 使用起始值
print("从10开始累加列表元素的总和是:", sum(numbers, 10)) # 输出结果:从10开始累加列表元素的总和是: 25
all() 函数
all() 函数用于判断给定的可迭代对象中的所有元素是否都为True(或者可迭代对象为空)。如果所有元素都为True,则返回True;如果有一个元素为False,则返回False。
# 定义一个列表
bool_list = [True, True, True]
# 使用all()函数判断列表中的所有元素是否都为True
all_true = all(bool_list)
# 打印结果
print("列表中的所有元素是否都为True:", all_true) # 输出结果:列表中的所有元素是否都为True: True
# 有一个元素为False的情况
bool_list_with_false = [True, False, True]
print("列表中的所有元素是否都为True(含False):", all(bool_list_with_false)) # 输出结果:列表中的所有元素是否都为True(含False): False
any() 函数
any() 函数用于判断给定的可迭代对象中是否至少有一个元素为True。如果有一个元素为True,则返回True;如果所有元素都为False(或可迭代对象为空),则返回False。
# 定义一个列表
bool_list = [False, False, False]
# 使用any()函数判断列表中是否至少有一个元素为True
any_true = any(bool_list)
# 打印结果
print("列表中是否至少有一个元素为True:", any_true) # 输出结果:列表中是否至少有一个元素为True: False
# 至少有一个元素为True的情况
bool_list_with_true = [False, True, False]
print("列表中是否至少有一个元素为True(含True):", any(bool_list_with_true)) # 输出结果:列表中是否至少有一个元素为True(含True): True