# Python 元组

> 原文： [https://www.programiz.com/python-programming/tuple](https://www.programiz.com/python-programming/tuple)

#### 在本文中，您将学习有关 Python 元组的所有知识。 更具体地说，什么是元组，如何创建它们，何时使用它们以及您应该熟悉的各种方法。

Python 中的元组类似于[列表](/python-programming/list)。 两者之间的区别在于，一旦分配了元组，我们就无法更改其元素，而可以更改列表中的元素。

* * *

## 创建一个元组

通过将所有项目（元素）放在圆括号`()`内并用逗号分隔，可以创建一个元组。 括号是可选的，但是，使用它们是一个好习惯。

元组可以具有任意数量的项，并且可以具有不同的类型（整数，浮点数，列表，[字符串](/python-programming/string)等）。

```py
# Different types of tuples

# Empty tuple
my_tuple = ()
print(my_tuple)

# Tuple having integers
my_tuple = (1, 2, 3)
print(my_tuple)

# tuple with mixed datatypes
my_tuple = (1, "Hello", 3.4)
print(my_tuple)

# nested tuple
my_tuple = ("mouse", [8, 4, 6], (1, 2, 3))
print(my_tuple)
```

**输出**

```py
()
(1, 2, 3)
(1, 'Hello', 3.4)
('mouse', [8, 4, 6], (1, 2, 3))
```

也可以在不使用括号的情况下创建元组。 这称为元组包装。

```py
my_tuple = 3, 4.6, "dog"
print(my_tuple)

# tuple unpacking is also possible
a, b, c = my_tuple

print(a)      # 3
print(b)      # 4.6
print(c)      # dog
```

**输出**：

```py
(3, 4.6, 'dog')
3
4.6
dog
```

用一个元素创建一个元组有点棘手。

括号内仅包含一个元素是不够的。 我们将需要一个逗号结尾来表明它实际上是一个元组。

```py
my_tuple = ("hello")
print(type(my_tuple))  # <class 'str'>

# Creating a tuple having one element
my_tuple = ("hello",)
print(type(my_tuple))  # <class 'tuple'>

# Parentheses is optional
my_tuple = "hello",
print(type(my_tuple))  # <class 'tuple'>
```

**输出**：

```py
<class 'str'>
<class 'tuple'>
<class 'tuple'>
```

* * *

## 访问元组元素

我们可以通过多种方式访问​​元组的元素。

### 1.索引

我们可以使用索引运算符`[]`访问元组中的项目，其中索引从 0 开始。

因此，具有 6 个元素的元组将具有从 0 到 5 的索引。尝试访问元组索引范围（在本示例中为 6，7，...）之外的索引将产生`IndexError`。

索引必须是整数，因此我们不能使用`float`或其他类型。 这将导致`TypeError`。

同样，使用嵌套索引访问嵌套元组，如下面的示例所示。

```py
# Accessing tuple elements using indexing
my_tuple = ('p','e','r','m','i','t')

print(my_tuple[0])   # 'p' 
print(my_tuple[5])   # 't'

# IndexError: list index out of range
# print(my_tuple[6])

# Index must be an integer
# TypeError: list indices must be integers, not float
# my_tuple[2.0]

# nested tuple
n_tuple = ("mouse", [8, 4, 6], (1, 2, 3))

# nested index
print(n_tuple[0][3])       # 's'
print(n_tuple[1][1])       # 4
```

**输出**：

```py
p
t
s
4
```

* * *

### 2.负索引

Python 允许对其序列进行负索引。

索引 -1 表示最后一项，-2 表示倒数第二项，依此类推。

```py
# Negative indexing for accessing tuple elements
my_tuple = ('p', 'e', 'r', 'm', 'i', 't')

# Output: 't'
print(my_tuple[-1])

# Output: 'p'
print(my_tuple[-6])
```

**输出**：

```py
t
p
```

* * *

### 3.切片

我们可以使用切片运算符冒号`:`访问元组中的一系列项目。

```py
# Accessing tuple elements using slicing
my_tuple = ('p','r','o','g','r','a','m','i','z')

# elements 2nd to 4th
# Output: ('r', 'o', 'g')
print(my_tuple[1:4])

# elements beginning to 2nd
# Output: ('p', 'r')
print(my_tuple[:-7])

# elements 8th to end
# Output: ('i', 'z')
print(my_tuple[7:])

# elements beginning to end
# Output: ('p', 'r', 'o', 'g', 'r', 'a', 'm', 'i', 'z')
print(my_tuple[:])
```

**输出**：

```py
('r', 'o', 'g')
('p', 'r')
('i', 'z')
('p', 'r', 'o', 'g', 'r', 'a', 'm', 'i', 'z')
```

通过考虑索引位于元素之间，可以最好地可视化切片，如下所示。 因此，如果要访问范围，则需要将元组中的部分切片的索引。

![Element Slicing in Python](img/e1ffea4f316ee85208db934ac59a2a89.png "Element Slicing")

Element Slicing in Python



* * *

## 修改元组

与列表不同，元组是不可变的。

这意味着一旦分配了元组的元素就无法更改。 但是，如果元素本身是可变数据类型（如列表），则可以更改其嵌套项目。

我们还可以将元组分配给不同的值（重新分配）。

```py
# Changing tuple values
my_tuple = (4, 2, 3, [6, 5])

# TypeError: 'tuple' object does not support item assignment
# my_tuple[1] = 9

# However, item of mutable element can be changed
my_tuple[3][0] = 9    # Output: (4, 2, 3, [9, 5])
print(my_tuple)

# Tuples can be reassigned
my_tuple = ('p', 'r', 'o', 'g', 'r', 'a', 'm', 'i', 'z')

# Output: ('p', 'r', 'o', 'g', 'r', 'a', 'm', 'i', 'z')
print(my_tuple)
```

**输出**：

```py
(4, 2, 3, [9, 5])
('p', 'r', 'o', 'g', 'r', 'a', 'm', 'i', 'z')
```

我们可以使用`+`运算符组合两个元组。 这称为**连接**。

我们也可以使用`*`运算符将**重复**元组中的元素给定次数。

`+`和`*`操作都产生一个新的元组。

```py
# Concatenation
# Output: (1, 2, 3, 4, 5, 6)
print((1, 2, 3) + (4, 5, 6))

# Repeat
# Output: ('Repeat', 'Repeat', 'Repeat')
print(("Repeat",) * 3)
```

**输出**：

```py
(1, 2, 3, 4, 5, 6)
('Repeat', 'Repeat', 'Repeat')
```

* * *

## 删除元组

如上所述，我们不能更改元组中的元素。 这意味着我们不能删除或删除元组中的项目。

但是，可以使用关键字 [del](/python-programming/keyword-list#del) 完全删除一个元组。

```py
# Deleting tuples
my_tuple = ('p', 'r', 'o', 'g', 'r', 'a', 'm', 'i', 'z')

# can't delete items
# TypeError: 'tuple' object doesn't support item deletion
# del my_tuple[3]

# Can delete an entire tuple
del my_tuple

# NameError: name 'my_tuple' is not defined
print(my_tuple)
```

**输出**：

```py
Traceback (most recent call last):
  File "<string>", line 12, in <module>
NameError: name 'my_tuple' is not defined
```

* * *

## 元组方法

元组不提供添加项目或删除项目的方法。 仅以下两种方法可用。

Python 元组方法的一些示例：

```py
my_tuple = ('a', 'p', 'p', 'l', 'e',)

print(my_tuple.count('p'))  # Output: 2
print(my_tuple.index('l'))  # Output: 3
```

**输出**：

```py
2
3
```

* * *

## 其他元组操作

### 1.元组成员资格测试

我们可以使用关键字`in`测试项目是否存在于元组中。

```py
# Membership test in tuple
my_tuple = ('a', 'p', 'p', 'l', 'e',)

# In operation
print('a' in my_tuple)
print('b' in my_tuple)

# Not in operation
print('g' not in my_tuple)
```

**输出**：

```py
True
False
True
```

* * *

### 2.遍历元组

我们可以使用`for`循环来遍历元组中的每个项目。

```py
# Using a for loop to iterate through a tuple
for name in ('John', 'Kate'):
    print("Hello", name)
```

**输出**：

```py
Hello John
Hello Kate
```

* * *

### 元组优于列表的优势

由于元组与列表非常相似，因此它们都在类似的情况下使用。 但是，在列表上实现元组具有某些优点。 以下列出了一些主要优点：

*   我们通常将元组用于异构（不同）数据类型，将列表用于同类（相似）数据类型。
*   由于元组是不可变的，因此遍历元组比使用`list`更快。 因此，性能略有提高。
*   包含不可变元素的元组可以用作字典的键。 对于列表，这是不可能的。
*   如果您的数据没有变化，将其实现为元组将保证其保持写保护。