Python reversed 函数
上次修改时间:2025 年 4 月 11 日
这篇综合指南探讨了 Python 的 reversed
函数,该函数返回序列的反向迭代器。我们将介绍内置序列、自定义对象以及反向迭代的实际示例。
基本定义
reversed
函数返回一个反向迭代器对象,该对象以相反的顺序访问元素。 它适用于任何实现 __reversed__
或支持序列协议 (__len__
和 __getitem__
) 的对象。
主要特点:返回一个迭代器(不是一个列表),保留原始序列,适用于字符串、列表、元组和自定义序列。 它具有内存效率,因为它不会创建新序列。
基本序列用法
这是一个简单的用法,使用不同的序列类型,展示了 reversed
如何处理列表、元组和字符串。
# With lists numbers = [1, 2, 3, 4, 5] print(list(reversed(numbers))) # [5, 4, 3, 2, 1] # With tuples colors = ('red', 'green', 'blue') print(tuple(reversed(colors))) # ('blue', 'green', 'red') # With strings text = "hello" print(''.join(reversed(text))) # "olleh"
此示例显示了 reversed
与不同序列类型的使用。 请注意,我们将迭代器转换为具体的类型(列表、元组、字符串)以进行显示。 原始序列保持不变。
对于字符串,我们使用 join
将反转后的字符重新组合成一个字符串。 reversed
函数适用于任何支持索引的序列。
具有 __reversed__ 的自定义对象
您可以通过实现 __reversed__
特殊方法使自定义对象与 reversed
一起使用。 此示例创建了一个 CountDown 类。
class CountDown: def __init__(self, start): self.start = start def __reversed__(self): n = 1 while n <= self.start: yield n n += 1 def __iter__(self): n = self.start while n > 0: yield n n -= 1 print("Normal iteration:") for x in CountDown(5): print(x) # 5, 4, 3, 2, 1 print("Reversed iteration:") for x in reversed(CountDown(5)): print(x) # 1, 2, 3, 4, 5
CountDown 类实现了 __iter__
和 __reversed__
。 正常迭代递减计数,而反向迭代递增计数。
这演示了如何自定义对象的反向迭代行为。 __reversed__
方法应返回一个迭代器。
Range 对象
reversed
函数可以高效地与 range 对象一起使用,创建一个反向迭代器,而无需在内存中生成所有数字。
# Forward range for i in range(5): print(i) # 0, 1, 2, 3, 4 # Reversed range for i in reversed(range(5)): print(i) # 4, 3, 2, 1, 0 # Large range (memory efficient) large_range = reversed(range(1, 1000001)) print(next(large_range)) # 1000000 print(next(large_range)) # 999999
此示例显示了 reversed
如何与 range 对象一起使用。 反向迭代具有内存效率,尤其是在处理大范围时。
range 对象专门实现了 __reversed__
,以提供这种高效的反向迭代,而无需存储所有数字。
错误处理
当与非序列类型一起使用时,reversed
函数会引发 TypeError
。 此示例显示了正确的错误处理。
try: print(list(reversed(42))) except TypeError as e: print(f"Error: {e}") # 'int' object is not reversible class NoReverse: pass try: print(list(reversed(NoReverse()))) except TypeError as e: print(f"Error: {e}") # 'NoReverse' object is not reversible
这些示例演示了 reversed
对不受支持的类型的行为。 没有 __reversed__
或序列协议的非序列对象和对象会引发 TypeError
。
要使类与 reversed
一起使用,请实现 __reversed__
或序列协议,如前所示。
性能注意事项
此示例将 reversed
的性能与反向迭代的替代方法进行比较。
import timeit def test_reversed(): return list(reversed([1, 2, 3, 4, 5])) def test_slice(): return [1, 2, 3, 4, 5][::-1] def test_manual(): lst = [1, 2, 3, 4, 5] return [lst[i] for i in range(len(lst)-1, -1, -1)] print("reversed():", timeit.timeit(test_reversed, number=1000000)) print("slice:", timeit.timeit(test_slice, number=1000000)) print("manual:", timeit.timeit(test_manual, number=1000000))
这会衡量不同的反向迭代方法。 对于迭代,reversed
通常是最快的。 切片会创建一个新列表,但对于小序列来说速度很快。
手动方法较慢且可读性较差,这说明了为什么在迭代场景中首选 reversed
。
最佳实践
- 用于迭代: 当您只需要迭代时,优先选择
reversed
而不是切片 - 实现 __reversed__: 对于支持反向迭代的自定义序列类型
- 考虑切片: 当您需要序列的反向副本时
- 处理错误: 当输入类型不确定时捕获 TypeError
- 记录行为: 清楚地记录 __reversed__ 的实现
资料来源
作者
列出所有 Python 教程。