跳至主要内容

Python 元组教程

了解 Python 元组:它是什么、如何创建、何时使用、可执行的操作以及您应该知道的各类函数。
· 10分钟 阅读

使用 AI 探索

与 Python 列表类似,元组是另一种标准数据类型,允许您以序列的形式存储值。它在需要与他人共享数据但不希望对方修改数据的场景中非常有用。对方可以使用这些数据值,但对原始共享数据不会产生任何更改。

在本教程中,您将详细了解 Python 元组:

python 元组教程

别忘了查看 DataCamp 的 Data Types for Data Science 课程,您可以在其中巩固并练习列表、字典、集合等数据结构的知识!或者,也可以看看这篇 Python 数据结构教程,进一步了解 Python 所使用的不同数据结构。

Python 元组

如上所述,您可以使用这种 Python 数据结构来存储一个不可变(或不可更改)且有序的项目序列。

元组使用 () 圆括号初始化,而列表使用 [] 方括号。这意味着要创建一个元组,您只需执行以下操作:

cake = ('c','a','k','e')
print(type(cake))
<class 'tuple'>

请记住,type() 是一个内置函数,可用于检查传入参数的数据类型。

元组既可以保存同质的值,也可以保存异质的值。但请注意,一旦您声明了这些值,就不能再更改它们:

mixed_type = ('C',0,0,'K','I','E')

for i in mixed_type:
    print(i,":",type(i))
C : <class 'str'>
0 : <class 'int'>
0 : <class 'int'>
K : <class 'str'>
I : <class 'str'>
E : <class 'str'>
# Try to change 0 to 'O'
mixed_type[1] = 'O'
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-16-dec29c289a95> in <module>()
----> 1 mixed_type[1] = 'O' # Trying to change 0 to 'O'


TypeError: 'tuple' object does not support item assignment

您会看到上述错误消息,是因为您不能更改元组内的值。

以下是创建元组的另一种方式:

numbers_tuple = 1,2,3,4,5
print(type(numbers_tuple))
<class 'tuple'>

元组与列表

您可能已经注意到,元组与列表非常相似。实际上,可以把它看作不可变的列表,这意味着一旦创建了元组,您就不能删除或更改其中项目的值,也不能添加新值。请看下面的示例:

numbers_tuple = (1,2,3,4,5)
numbers_list = [1,2,3,4,5]

# Append a number to the tuple
numbers_tuple.append(6)
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-26-e47776d745ce> in <module>()
      3 
      4 # Append a number to the tuple
----> 5 numbers_tuple.append(6)


AttributeError: 'tuple' object has no attribute 'append'

这会抛出错误,因为您不能从元组中删除或向其添加元素,而列表可以。

# Append numbers to the list
numbers_list.append(6)
numbers_list.append(7)
numbers_list.append(8)

# Remove a number from the list
numbers_list.remove(7)
print(numbers_list)
[1, 2, 3, 4, 5, 6, 8]

但如果元组是不可变的,为什么还要用它呢?

不仅因为它们为数据值提供“只读”访问,而且它们也比列表更快。请看以下代码片段:

import timeit
timeit.timeit('x=(1,2,3,4,5,6,7,8,9)', number=100000)
0.0018976779974764213
timeit.timeit('x=[1,2,3,4,5,6,7,8,9]', number=100000)
0.019868606992531568

对于元组来说,不可变究竟意味着什么?

根据 Python 官方文档,不可变对象是“具有固定值的对象”,但“值”这个词相对含糊,对元组更准确的术语是“id”。“id”是对象在内存中的位置标识。

让我们更深入地看一下:

# Tuple 'n_tuple' with a list as one of its item.
n_tuple = (1, 1, [3,4])

#Items with same value have the same id.
id(n_tuple[0]) == id(n_tuple[1])
True
#Items with different value have different id.
id(n_tuple[0]) == id(n_tuple[2])
False
id(n_tuple[0])
4297148528
id(n_tuple[2])
4359711048
n_tuple.append(5)
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-40-3cd258e024ff> in <module>()
----> 1 n_tuple.append(5)


AttributeError: 'tuple' object has no attribute 'append'

我们无法向元组追加元素,因此如上会报错。这也是元组被称为不可变的原因。但您始终可以这样做:

n_tuple[2].append(5)
n_tuple
(1, 1, [3, 4, 5])

这样实际上改变了原始元组。那么为什么元组仍被称为不可变呢?

这是因为,即使您向其中的列表追加了 5,该列表在元组中的 id 仍保持不变。

id(n_tuple[2])
4359711048

总结一下目前为止您学到的内容:

某些元组(仅包含不可变对象:字符串等)是不可变的,而另一些元组(包含一个或多个可变对象:列表等)则是可变的。不过,这往往是 Python 开发者之间的一个可讨论话题,完全理解还需要更多背景知识。关于此话题的更深入文章请见这里。目前,我们不妨将元组一般视为不可变。

  • 由于不可变特性,您不能向元组添加元素。元组没有 append() 或 extend() 方法,
  • 同样地,您也不能从元组中移除元素。元组没有 remove() 或 pop() 方法,
  • 您可以在元组中查找元素,因为这不会改变元组,
  • 您还可以使用 in 运算符检查某元素是否存在于元组中。

因此,如果您要定义一组常量值,并且只是遍历它,请使用元组而不是列表。它比使用列表更快,也更安全,因为元组中的数据是“写保护”的。

如果您想进一步了解 Python 列表,请务必查看这篇教程!

常见元组操作

Python 提供了多种处理元组的方式。下面通过示例看看一些重要操作。

元组切片

元组中第一个值的索引为 0。与 Python 列表类似,您可以结合使用索引值与方括号 [] 来访问元组中的元素:

numbers = (0,1,2,3,4,5)
numbers[0]
0

您也可以在元组中使用负索引:

numbers[-1]
5

索引用于获取单个元素,而切片则允许您获取子集。当您输入想要提取的范围时,这称为范围切片。范围切片的一般格式为:

[Start index (included):Stop index (excluded):Increment]

其中 Increment 为可选参数,默认增量为 1。

# Item at index 4 is excluded
numbers[1:4]
(1, 2, 3)
# This provides all the items in the tuple
numbers[:]
(0, 1, 2, 3, 4, 5)
# Increment = 2
numbers[::2]
(0, 2, 4)

提示:您也可以使用负增量值来反转元组。

numbers[::-1]
(5, 4, 3, 2, 1, 0)

元组相加

您可以将多个元组合并形成新元组。加法操作对元组而言就是连接(拼接)。

x = (1,2,3,4)
y = (5,6,7,8)

# Combining two tuples to form a new tuple
z = x + y 

print(z)
(1, 2, 3, 4, 5, 6, 7, 8)
y = [5,6,7,8]
z = x + y
print(z)
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-55-d352c6414a4c> in <module>()
      1 y = [5,6,7,8]
----> 2 z = x + y
      3 print(z)


TypeError: can only concatenate tuple (not "list") to tuple

只能将相同数据类型相加或合并。因此,将元组与列表合并会报错。

元组乘法

乘法操作会对元组进行重复。

x = (1,2,3,4)
z = x*2
print(z)
(1, 2, 3, 4, 1, 2, 3, 4)

元组函数

与 Python 列表不同,元组由于其不可变性,没有 append()、remove()、extend()、insert() 和 pop() 等方法。不过,还有许多其他内置函数可用于处理元组:

count() 和 len()

count() 返回某个项目在元组中出现的次数。

a = [1,2,3,4,5,5]
a.count(5)
2

使用 len() 函数,您可以返回元组的长度:

a = (1,2,3,4,5)
print(len(a))
5

any()

您可以使用 any() 判断元组中是否存在任一元素为可迭代对象。如果是,则返回 True,否则返回 False。

a = (1,)
print(any(a))
True

请注意上面元组 a 的声明中带有 ,。如果在初始化只有一个元素的元组时不加逗号,Python 会认为您只是多写了一对括号(这无伤大雅),但数据类型就不是元组了。因此,声明单元素元组时请记得添加逗号。

回到 any() 函数:在布尔上下文中,元素的具体值并不重要。空元组为 false,至少包含一个元素的元组为 true。

b = ()
print(any(b))
False

当您在程序中某处调用一个元组,并希望确保该元组已被填充时,此函数会很有用。

tuple()

使用 tuple() 将其他数据类型转换为元组。例如,在下面的代码片段中,您将一个 Python 列表转换为元组。

a_list = [1,2,3,4,5]
b_tuple = tuple(a_list)
print(type(b_tuple))
<class 'tuple'>

min() 和 max()

max() 返回元组中的最大元素,而 min() 则返回最小元素。请看以下示例:

print(max(a))
print(min(a))
5
A

这也适用于包含字符串数据类型的元组。

# The string 'Apple' is automatically converted into a sequence of characters. 
a = ('Apple') 
print(max(a))
p

sum()

使用该函数可以返回元组中所有项目的总和。它只能用于数值类型。

sum(a)
28

sorted()

要返回按排序顺序排列元素的结果,请使用 sorted(),如下例所示:

a = (6,7,4,2,1,5,3)
sorted(a)
[1, 2, 3, 4, 5, 6, 7]

需要注意的是,返回类型是列表而不是元组。原始元组 a 中的顺序不会改变,a 的数据类型仍然是元组。

加餐:一次赋多个值

元组的一个妙用是可以用它一次性为多个变量赋值。请看:

a = (1,2,3)
(one,two,three) = a
print(one)
1

a 是一个包含三个元素的元组,而 (one,two,three) 是包含三个变量的元组。将 (one,two,three) 赋值为元组 a 会按顺序把 a 的各个值分别赋给变量 one、two 和 three。当您需要将一系列值赋给一个元组中存放的序列时,这个技巧非常实用。

恭喜!

您已读完本次元组教程!在此过程中,您了解了什么是 Python 元组、如何初始化它们、可以用哪些最常见的操作来处理它们,以及有哪些常用方法可以帮助您从这些 Python 数据结构中获取更多洞见。作为加餐,您还学会了如何一次性为元组解包并赋多个值。

主题