python元组_python – 为什么元组比列表更快?

这篇博客探讨了在Python中,从常量构建列表和元组的速度差异。结果显示,从常量创建元组的速度通常比使用变量值构建列表快三倍。这是因为元组在编译时可以被优化为不可变的常量,而列表作为可变对象无法享受同样的优化。这种性能差异归因于元组的简单性和不可变性。
部署运行你感兴趣的模型镜像

报告的“构造速度”比率仅适用于恒定元组(其项目由字面量表示)。仔细观察(并在您的机器上重复 – 您只需要在shell /命令窗口中键入命令!)…:

$ python3.1 -mtimeit -s'x,y,z=1,2,3' '[x,y,z]'

1000000 loops, best of 3: 0.379 usec per loop

$ python3.1 -mtimeit '[1,2,3]'

1000000 loops, best of 3: 0.413 usec per loop

$ python3.1 -mtimeit -s'x,y,z=1,2,3' '(x,y,z)'

10000000 loops, best of 3: 0.174 usec per loop

$ python3.1 -mtimeit '(1,2,3)'

10000000 loops, best of 3: 0.0602 usec per loop

$ python2.6 -mtimeit -s'x,y,z=1,2,3' '[x,y,z]'

1000000 loops, best of 3: 0.352 usec per loop

$ python2.6 -mtimeit '[1,2,3]'

1000000 loops, best of 3: 0.358 usec per loop

$ python2.6 -mtimeit -s'x,y,z=1,2,3' '(x,y,z)'

10000000 loops, best of 3: 0.157 usec per loop

$ python2.6 -mtimeit '(1,2,3)'

10000000 loops, best of 3: 0.0527 usec per loop

我没有做3.0的测量,因为我当然没有它 – 它完全过时,并没有绝对没有理由保持它,因为3.1是优于它在任何方式(Python 2.7,如果你可以升级到它,测量在每个任务中比2.6快几乎20% – 和2.6,如你所见,比3.1快 – 所以,如果你认真对待性能,Python 2.7是真正唯一的版本要去!)。

无论如何,这里的关键点是,在每个Python版本中,从常量文字构建一个列表的速度或者稍微慢一点,而不是使用变量引用的值。但元组的行为非常不同 – 从常量文字构建元组通常是由变量引用的值的三倍快!你可能想知道这是怎么回事,对吗? – )

答案:由常量文字组成的元组可以很容易地被Python编译器识别为一个不可变的常量文字本身:因此它基本上只构建一次,当编译器将源代码转换为字节码,并保存在“常量表“的相关功能或模块。当这些字节码执行时,它们只需要恢复预建的常量元组 – hey presto! – )

这种简单的优化不能应用于列表,因为列表是一个可变对象,因此如果相同的表达式[例如[1,2,3])执行两次(在循环中 – timeit模块使循环开启你的代码;-),一个新的新的列表对象每次都被重新构造 – 并且该构造(像编译器不能简单地将其标识为编译时常量和不可变对象的构造一个元组)需要一点时间。

也就是说,元组构造(当两个结构实际上必须发生)仍然是列表构建的两倍快 – 这种差异可以由元组的简单性来解释,其他答案已经反复提到。但是,这种简单性不会导致6倍或更快的加速,因为你观察到如果你只比较列表和元组的构造与简单的常量文字作为他们的项目!_)

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

### 关于 Python 元组中 `__next__` 方法的用法 在 Python 中,元组本身并不是迭代器,但它是一个可迭代对象(Iterable),可以通过 `iter()` 函数将其转换为迭代器。一旦转换为迭代器,就可以使用 `__next__()` 方法逐个访问元组中的元素。 #### 转换元组为迭代器并使用 `__next__()` 方法 要将元组转换为迭代器,可以使用内置函数 `iter()`。之后,通过调用该迭代器的 `__next__()` 方法逐一获取元组中的元素[^2]。如果尝试访问超出范围的元素,则会引发 `StopIteration` 异常。 以下是一个完整的例子: ```python # 定义一个元组 my_tuple = (10, 20, 30, 40) # 将元组转换为迭代器 iterator = iter(my_tuple) # 使用 __next__() 遍历元组 try: while True: element = iterator.__next__() print(element) except StopIteration: # 当没有更多元素时,捕获 StopIteration 异常 pass ``` 上述代码展示了如何利用 `__next__()` 方法逐步提取元组中的每一个元素,并处理可能发生的 `StopIteration` 异常。 #### 判断是否为迭代器 为了验证某个对象是否为迭代器,可以使用 `isinstance()` 结合 `collections.abc.Iterator` 类型进行检查[^3]。例如: ```python from collections.abc import Iterator # 检查原始元组是否为迭代器 print(isinstance(my_tuple, Iterator)) # 输出 False # 检查经过 iter() 处理后的对象是否为迭代器 converted_iterator = iter(my_tuple) print(isinstance(converted_iterator, Iterator)) # 输出 True ``` 这表明只有当元组被显式转换成迭代器后,才能真正支持 `__next__()` 方法的操作。 #### 迭代器与可迭代对象的区别 需要注意的是,虽然元组是一种可迭代对象(因为它实现了 `__iter__()` 方法),但其本身并不具备迭代器的功能(即未实现 `__next__()` 方法)。因此,在实际应用中需先借助 `iter()` 函数完成这一转化过程[^5]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值