在 Python 中,tuple(元组)是一种 有序的、不可变 的集合。与 list(列表)类似,它可以存储多个不同类型的元素,但不同点在于 tuple 一旦创建后,里面的元素就不能被修改、添加或删除。

特点

  • 有序性:tuple 中的元素是有序排列的,可以通过索引来访问,如 tuple[0]。
  • 不可变性:tuple 一旦创建,元素无法更改(无法增加、删除或改变元素值)。
  • 使用小括号:tuple 使用小括号 () 来创建,元素之间用逗号隔开。

创建元组的方式

my_tuple = (1, 2, 3, \'a\', \'b\')

# 单个元素的元组(需要一个逗号)
single_element_tuple = (5,)

为什么单个元素的元组(需要一个逗号)?为了让 Python 确认你要创建的是一个单元素的元组,而不是普通的括号包裹数值,需要在单个元素后加逗号。

范例解释

#没有逗号的情况
single_element_tuple = (5)
print(type(single_element_tuple)) # 输出 <class \'int\'>
#加上逗号的情况
single_element_tuple = (5,)
print(type(single_element_tuple)) # 输出 <class \'tuple\'>

语法糖 自动被打包成一个 元组(tuple)

在 Python 中,当使用逗号分隔多个值时,这些值会自动被打包成一个元组(tuple),即使你不明确使用圆括号。

packed_tuple = 1, 2, 3 # 没有括号
print(packed_tuple) # (1, 2, 3)
print(type(packed_tuple))# <class \'tuple\'>

访问元组中的元素

my_tuple = (1, 2, 3, \'a\', \'b\')
print(my_tuple[0]) # 输出 1
print(my_tuple[3]) # 输出 \'a\'

不可变性

my_tuple = (1, 2, 3)
# my_tuple[0] = 10 # 这行会报错,因为元组不可修改

元组(Tuple)的常用操作

操作
描述
范例
结果
len() 取得元组的长度 len((1, 2, 3)) 3
index() 查找指定元素的索引值 (1, 2, 3).index(2) 1
count() 计算指定元素出现的次数 (1, 2, 2, 3).count(2) 2
元组解包(Unpacking) 将元组中的元素赋值给变数 a, b, c = (1, 2, 3) a=1, b=2, c=3
切片(Slicing) 取得元组中的部分元素 (1, 2, 3, 4)[1:3] (2, 3)
连接(Concatenation) 连接两个或多个元组 (1, 2) + (3, 4) (1, 2, 3, 4)
重复(Repetition) 重复元组中的元素多次 (\'a\', \'b\') * 2 (\'a\', \'b\', \'a\', \'b\')
成员检查(in) 检查元素是否在元组中 2 in (1, 2, 3) True
比较(Comparison) 比较两个元组的大小 (1, 2, 3) > (1, 2, 1) True
迭代(Iteration) 遍历元组中的所有元素 for x in (1, 2, 3): print(x) 1 2 3

元组解包(Unpacking)

想像元组是装东西的「盒子」,里面放了不同的三个数字。比如:1、2 和 3。

my_tuple = (1, 2, 3)

解包(Unpacking) 就像是你把这些东西从盒子里拿出来,分给不同的人(变数)。比如:

a, b, c = my_tuple

这里,a 得到了 1,b 得到了 2,c 得到了 3。就像是你把盒子里的东西一个一个分配给不同的变数。

所以元组解包(Unpacking) 有点像是javascript的解构概念?

是的,元组解包(Unpacking) 在 Python 中的概念,确实与 JavaScript 的解构赋值(Destructuring Assignment) 非常相似。两者都涉及将数组或对象(在 JavaScript 中)或元组(在 Python 中)的值拆解出来,并赋值给不同的变数。

比较范例

Python 中的元组解包(Unpacking)

my_tuple = (1, 2, 3)
a, b, c = my_tuple
print(a, b, c) # 1 2 3

JavaScript 中的解构赋值(Destructuring Assignment)

const myArray = [1, 2, 3];
const [a, b, c] = myArray;
console.log(a, b, c); // 1 2 3

主要类似之处:

多个值的分配:两者都从多个值的容器(元组或数组)中,将每个元素提取出来,并分配给不同的变数。简化代码:这些语法让我们不用手动逐个提取元素,简化了代码的书写。

问题:如何交换两个变数的值?

Python 的简单方法Python 使用了元组这个概念,类似于打包礼物的包裹。

  • 首先,它把 b 和 a 这两个东西(香蕉和苹果)包在一起变成一个包裹packing。
  • 然后它打开这个包裹unpacking,分别把里面的香蕉给 a,苹果给 b。

a = apple
b = banana

# 这一步发生了 tuple packing 和 unpacking
a, b = banana, apple #右边的值(香蕉和苹果)包在一起变成一个包裹。(banana, apple )

# 现在 a 和 b 的值已经交换
print(a) # 10
print(b) # 5

使用*解包:更灵活的资料处理

在 Python 中,*号在解包(unpacking)时扮演着非常重要的角色,它让我们可以更灵活地处理可迭代对象(如列表、元组等)。

基本用法

将可迭代对象的元素分配给多个变数:当我们知道可迭代对象的元素个数时,可以直接将元素一一分配给变数。但当元素个数不确定或想将多余的元素收集到一个变数中时,* 就派上用场了

numbers = [1, 2, 3, 4, 5]
a, b, *c = numbers
print(a) # 输出 1
print(b) # 输出 2
print(c) # 输出 [3, 4, 5]

在这个例子中,*c 表示将剩余的元素收集到列表 c 中。

将字典解包:

* 也可以用于解包字典。

person = {\'name\': \'Alice\', \'age\': 30, \'city\': \'New York\'}
name, *rest = person.items()
print(name) # 输出 (\'name\', \'Alice\')
print(rest) # 输出 [(\'age\', 30), (\'city\', \'New York\')]

进阶用法

  • 函数参数:
    • * 可以用来表示可变长度的位置参数。

def greet(*names):
for name in names:
print(f"Hello, {name}!")

greet(\'Alice\', \'Bob\', \'Charlie\')

  • 函数返回值:
    • * 可以用来将可迭代对象的元素拆开作为函数的返回值。

def split_list(numbers):
return numbers[:2], *numbers[2:]

a, *b = split_list([1, 2, 3, 4])
print(a) # 输出 [1, 2]
print(b) # 输出 [3, 4]

注意事项:*只能出现在赋值语句的左侧或函数定义的参数列表中。

什么是 Mutable objects in tuples?

在 Python 中,元组(tuple)是不可变的immutable,这意味着一旦创建了元组,里面的元素就不能被修改或重新赋值。然而,元组可以包含可变的对象,这些可变对象可以在元组内被修改,尽管元组本身仍然是不可变的。这就是可变对象在元组中的情况。

例子解释:

  • 元组本身不可变:元组中的每个元素的值和位置不能被改变。例如,my_tuple = (1, 2, 3) 创建了一个包含数字 1、2 和 3 的元组。你不能改变元组中的数字,像 my_tuple[0] = 5 这样的操作会报错。

  • 元组中的可变对象:虽然元组本身不可变,但如果元组内包含可变对象,如列表或字典,这些对象的内容是可以改变的。

my_tuple = (1, 2, [3, 4])

# 尝试改变元组内的列表
my_tuple[2].append(5)
print(my_tuple) #(1, 2, [3, 4, 5])

在这里,my_tuple[2] 是一个列表 [3, 4],虽然元组是不可变的,但这个列表是可变的,所以我们可以对列表进行修改,像 append(5) 这样操作。

哪些可以当作字典的 key?

在 Python 中,字典的 key 必须是不可变(immutable)的物件。这意味着可以作为字典 key 的物件类型包括:

  • 字串(string)
  • 整数(integer)
  • 浮点数(float)
  • 元组(tuple),但元组中的元素也必须是不可变的。

现在来看两个例子:(\'tom\', [14, 23, 26])这个元组内包含了一个可变的列表 [14, 23, 26]。由于列表是可变的,这个元组不能作为字典的 key。

[\'string\', (15, 16)]这是个列表,而列表本身是可变的,所以它不能作为字典的 key。

哪些可以当作字典的 key?

  • (\'tom\', [14, 23, 26]):❌ 不可以,因为包含可变的列表。
  • [\'string\', (15, 16)]:❌ 不可以,因为列表是可变的。
  • 如果你要用元组作为字典的 key,该元组内的所有元素都必须是不可变的,例如 (\'tom\', (14, 23, 26)) 就是合法的字典 key,因为元组内的所有元素都是不可变的。