摘要: 元组(Tuple)本身是不可变的,因此它不像列表那样拥有大量用于修改数据的方法。不过,在实际使用元组时,
count()和index()是最常用的两个方法。此外,Python 还提供了sorted()等函数,可以对元组中的数据进行排序。本文将介绍这几个常用操作,并重点讲解参数、返回值以及容易遇到的错误。
元组有哪些常用方法?
元组是不可变对象,所以它能够直接使用的方法其实并不多。
最常用的两个方法是:
| 方法 | 作用 |
|---|---|
count() |
统计某个元素出现了多少次 |
index() |
查找某个元素第一次出现的位置 |
除此之外,还经常会配合一些 Python 内置函数使用,例如:
| 函数 | 作用 |
|---|---|
sorted() |
对元组中的元素进行排序,并返回一个新的列表 |
len() |
获取元组中元素的数量 |
max() |
获取最大值 |
min() |
获取最小值 |
本篇主要学习:
count()
index()
sorted()
count():统计元素出现的次数
count() 的作用非常简单:
统计某个元素在元组中出现了多少次。
基本语法:
tuple.count(value)
其中:
tuple:要进行统计的元组。count():统计次数的方法。value:需要统计的元素。
例如:
programming_languages = ("Rust", "Java", "Python", "C++", "Rust")
result = programming_languages.count("Rust")
print(result)
# 2
因为:
("Rust", "Java", "Python", "C++", "Rust")
↑ ↑
Rust Rust
Rust 一共出现了两次。
所以:
programming_languages.count("Rust")
返回:
2
count() 找不到元素时会怎样?
如果指定的元素不存在,count() 不会报错。
它会直接返回:
0
例如:
programming_languages = ("Rust", "Java", "Python", "C++", "Rust")
print(programming_languages.count("JavaScript"))
# 0
因为:
JavaScript
↓
元组中不存在
↓
出现次数 = 0
因此可以记住:
count()找不到元素时返回0。
count() 必须提供一个参数
count() 需要知道:
你到底想统计哪个元素?
因此下面的写法是错误的:
programming_languages = ("Rust", "Java", "Python", "C++", "Rust")
programming_languages.count()
会产生:
TypeError
类似:
TypeError: tuple.count() takes exactly one argument (0 given)
意思是:
count()必须接收一个参数,但你一个参数都没有提供。
正确写法:
programming_languages.count("Rust")
index():查找元素的索引
另一个非常常用的元组方法是:
index()
它的作用是:
查找某个元素第一次出现时的索引位置。
基本语法:
tuple.index(value)
例如:
programming_languages = ("Rust", "Java", "Python", "C++", "Rust")
result = programming_languages.index("Java")
print(result)
# 1
为什么结果是 1?
因为元组的索引从 0 开始:
索引: 0 1 2 3 4
↓ ↓ ↓ ↓ ↓
元素: Rust Java Python C++ Rust
↑
index = 1
所以:
programming_languages.index("Java")
得到:
1
index() 如果出现多次怎么办?
这是一个非常重要的细节。
例如:
programming_languages = (
"Rust",
"Java",
"Python",
"C++",
"Rust",
"Python"
)
其中:
Python
出现了两次:
索引: 0 1 2 3 4 5
↓ ↓ ↓ ↓ ↓ ↓
元素: Rust Java Python C++ Rust Python
↑ ↑
第一次 第二次
如果直接使用:
print(programming_languages.index("Python"))
结果是:
2
因为:
index()默认返回第一次找到的元素的索引。
它不会把所有匹配的位置都返回出来。
index() 可以指定开始查找的位置
index() 支持一个可选参数:
start
完整形式可以写成:
tuple.index(value, start)
意思是:
从指定的索引开始查找。
例如:
programming_languages = (
"Rust",
"Java",
"Python",
"C++",
"Rust",
"Python"
)
print(programming_languages.index("Python", 3))
# 5
这里:
programming_languages.index("Python", 3)
表示:
从索引
3开始寻找Python。
因此:
索引: 0 1 2 3 4 5
↓ ↓ ↓ ↓ ↓ ↓
元素: Rust Java Python C++ Rust Python
↑ ↑
从这里开始查找
索引 2 的 Python 在查找范围之前,因此不会被找到。
最终找到:
索引 5
index() 还可以指定结束位置
除了开始索引之外,还可以指定:
stop
完整形式:
tuple.index(value, start, stop)
意思是:
从
start开始查找,一直查找到stop,但不包含stop。
例如:
programming_languages = (
"Rust",
"Java",
"Python",
"C++",
"Rust",
"Python",
"JavaScript",
"Python"
)
result = programming_languages.index("Python", 2, 5)
print(result)
# 2
这里:
index("Python", 2, 5)
表示:
从索引 2 开始
查找到索引 5 之前
不包含索引 5
实际查找范围是:
索引: 2 3 4
↓ ↓ ↓
元素: Python C++ Rust
第一个元素就是:
Python
所以返回:
2
index() 的 start 和 stop 规则
可以记住:
tuple.index(value, start, stop)
其中:
| 参数 | 作用 |
|---|---|
value |
要查找的元素 |
start |
从哪个索引开始查找 |
stop |
查找到哪个索引之前停止 |
和切片一样:
stop不包含在查找范围内。
index() 找不到元素会怎样?
和 count() 不一样。
如果 index() 找不到指定元素,Python 会产生:
ValueError
例如:
programming_languages = (
"Rust",
"Java",
"Python",
"C++",
"Rust"
)
programming_languages.index("JavaScript")
会产生类似:
ValueError: tuple.index(x): x not in tuple
意思是:
元组中不存在要查找的元素。
所以需要特别区分:
| 方法 | 找不到元素时 |
|---|---|
count() |
返回 0 |
index() |
抛出 ValueError |
这是学习这两个方法时非常重要的区别。
count() 和 index() 的区别
这两个方法很容易混淆。
可以这样理解:
count()
↓
这个东西出现了几次?
index()
↓
这个东西第一次出现在哪里?
例如:
languages = ("Python", "Java", "Python", "Rust")
使用:
print(languages.count("Python"))
# 2
得到的是:
Python 出现了 2 次
而:
print(languages.index("Python"))
# 0
得到的是:
Python 第一次出现在索引 0
sorted():对元组进行排序
除了元组自身的方法之外,还经常使用 Python 的内置函数:
sorted()
sorted 可以理解为:
把一个可迭代对象中的元素排序,并返回一个新的列表。
它不仅可以处理元组,也可以处理:
- 列表
- 字符串
- 集合
- 字典
- 其他可迭代对象
例如:
numbers = (13, 2, 78, 3, 45, 67, 18, 7)
result = sorted(numbers)
print(result)
# [2, 3, 7, 13, 18, 45, 67, 78]
注意这里有一个非常重要的地方:
sorted()返回的是列表(list),不是元组。
也就是说:
numbers
原本是:
tuple
而:
sorted(numbers)
得到的是:
list
可以验证:
numbers = (13, 2, 78, 3)
result = sorted(numbers)
print(type(numbers))
# <class 'tuple'>
print(type(result))
# <class 'list'>
sorted() 不会修改原来的元组
因为元组本身是不可变的。
例如:
numbers = (13, 2, 78, 3)
result = sorted(numbers)
print(numbers)
# (13, 2, 78, 3)
print(result)
# [2, 3, 13, 78]
原来的:
numbers
完全没有发生变化。
sorted() 做的是:
原元组
↓
sorted()
↓
创建一个新的列表
sorted() 和 list.sort() 有什么区别?
学习过列表的同学可能会见过:
list.sort()
这两个操作非常容易混淆。
sorted() |
sort() |
|---|---|
| 内置函数 | 列表方法 |
| 可以处理各种可迭代对象 | 只能用于列表 |
| 返回新的列表 | 直接修改原列表 |
| 不修改原对象 | 会修改原列表 |
例如:
numbers = (3, 1, 2)
result = sorted(numbers)
print(result)
# [1, 2, 3]
这里可以处理元组。
而:
numbers = [3, 1, 2]
numbers.sort()
print(numbers)
# [1, 2, 3]
sort() 只能用于列表。
使用 reverse=True 进行降序排序
默认情况下:
sorted()
按照升序排列。
例如:
numbers = (5, 2, 8, 1, 3)
print(sorted(numbers))
# [1, 2, 3, 5, 8]
如果希望从大到小排序,可以使用:
reverse=True
例如:
numbers = (5, 2, 8, 1, 3)
print(sorted(numbers, reverse=True))
# [8, 5, 3, 2, 1]
可以简单理解:
reverse=False
↓
正常顺序 → 升序
reverse=True
↓
反向顺序 → 降序
sorted() 的 key 参数
sorted() 还有一个非常实用的参数:
key
key 用来告诉 Python:
排序时应该根据什么规则来比较元素。
例如,有这样一个元组:
programming_languages = (
"Rust",
"Java",
"Python",
"C++",
"Rust",
"Python"
)
如果我们希望:
按字符串长度排序。
可以写:
result = sorted(programming_languages, key=len)
print(result)
# ['C++', 'Rust', 'Java', 'Rust', 'Python', 'Python']
这里:
key=len
表示:
排序时,把每个字符串的长度作为排序依据。
例如:
"C++" → 3
"Rust" → 4
"Java" → 4
"Python" → 6
于是 Python 就会按照字符串长度进行排序。
什么是 key?
这里的:
key=len
初学者可能会觉得有些奇怪。
注意:
key=len
而不是:
key=len()
因为 key 需要的是一个函数。
Python 会在排序过程中自动调用这个函数。
可以简单理解成:
sorted()
↓
拿到一个元素
↓
交给 len()
↓
得到长度
↓
根据长度进行排序
例如:
"Rust"
↓
len("Rust")
↓
4
然后根据这个 4 进行排序。
key 参数不只可以使用 len()
key 可以接收一个函数,因此可以根据不同需求制定排序规则。
例如按照字符串长度:
languages = ("Python", "C", "JavaScript", "Go")
print(sorted(languages, key=len))
# ['C', 'Go', 'Python', 'JavaScript']
这里排序依据不是字符串本身,而是:
字符串长度
reverse 和 key 可以一起使用
key 和 reverse 可以同时使用。
例如:
languages = ("Python", "C", "JavaScript", "Go")
result = sorted(languages, key=len, reverse=True)
print(result)
# ['JavaScript', 'Python', 'Go', 'C']
执行过程可以理解为:
按照字符串长度排序
↓
然后反向排列
↓
得到从长到短的结果
元组常用方法和函数速查表
| 名称 | 类型 | 作用 | 返回结果 |
|---|---|---|---|
count() |
元组方法 | 统计元素出现次数 | int |
index() |
元组方法 | 查找元素索引 | int |
sorted() |
内置函数 | 排序 | 新的 list |
len() |
内置函数 | 获取元素数量 | int |
max() |
内置函数 | 获取最大值 | 元素本身 |
min() |
内置函数 | 获取最小值 | 元素本身 |
count()、index()、sorted() 对比
可以把这三个操作记成:
count()
↓
数一数有几个
index()
↓
找一找在哪里
sorted()
↓
排一排顺序
例如:
languages = ("Python", "Java", "Python", "Rust")
统计:
print(languages.count("Python"))
# 2
查找:
print(languages.index("Python"))
# 0
排序:
print(sorted(languages))
# ['Java', 'Python', 'Python', 'Rust']
常见错误
❌ 把 sorted() 当成元组的方法
错误理解:
languages.sorted()
会产生错误,因为:
sorted()
不是元组的方法。
正确写法:
sorted(languages)
❌ 以为 sorted() 会返回元组
例如:
languages = ("Rust", "Python", "Java")
result = sorted(languages)
print(type(result))
# <class 'list'>
sorted() 返回的是:
list
不是:
tuple
如果确实需要重新得到元组,可以再进行转换:
languages = ("Rust", "Python", "Java")
result = tuple(sorted(languages))
print(result)
# ('Java', 'Python', 'Rust')
❌ 以为 index() 会返回所有匹配位置
例如:
languages = ("Python", "Java", "Python", "Rust")
print(languages.index("Python"))
# 0
它只返回:
第一次出现的位置。
如果需要查找所有符合条件的位置,就需要使用循环等其他方式处理。
❌ 忘记 index() 找不到元素会报错
languages = ("Python", "Java", "Rust")
languages.index("C++")
会产生:
ValueError
如果只是想判断某个元素是否存在,可以先使用:
"C++" in languages
得到:
False
学习小结
元组本身是不可变的,所以常用方法并不像列表那么多。
最重要的是:
count()
用于统计元素出现次数:
languages = ("Python", "Java", "Python")
print(languages.count("Python"))
# 2
index()
用于查找元素第一次出现的位置:
languages = ("Python", "Java", "Python")
print(languages.index("Python"))
# 0
还可以指定查找范围:
languages.index("Python", 1, 3)
sorted()
用于对元组中的元素进行排序:
numbers = (3, 1, 2)
print(sorted(numbers))
# [1, 2, 3]
需要特别记住:
sorted()不会修改原来的元组,而是返回一个新的列表。
总结
count()用于统计某个元素在元组中出现的次数。count()找不到元素时会返回0。count()必须提供一个要统计的元素。index()用于查找某个元素第一次出现时的索引。index()可以使用start和stop参数限制查找范围。index()找不到元素时会产生ValueError。sorted()是 Python 的内置函数,不是元组的方法。sorted()可以对元组进行排序,并返回一个新的列表。sorted()默认按照升序排序,可以通过reverse=True实现降序。key可以自定义排序规则,例如使用key=len按字符串长度排序。- 元组是不可变的,因此这些操作主要用于查询和处理数据,而不是修改元组本身。
记住三个关键词:
count()负责“数”,index()负责“找”,sorted()负责“排”。