关于python:传递需要列表或元组的参数时要传递什么?

What to pass when passing arguments where a list or tuple is required?

我应该使用以下哪项?为什么?

1
2
3
import numpy as np
a = np.zeros([2, 3])
b = np.zeros((2, 3))

在很多情况下,你可以用任何一种方式来传递论点,我只是想知道一个是否更像Python,或者是否有其他的原因,其中一个应该比另一个更受欢迎。

我研究了这个问题,人们试图解释元组和列表之间的区别。这不是我感兴趣的,除非有我应该关心的理由,当然我忽略了!

更新:

虽然numpy被用作一个例子,但它通常适用于python。非numpy示例如下:

1
2
a = max([1, 2, 3, 5, 4])
b = max((1, 2, 3, 5, 4))

我没有编辑上面的内容,因为有些答案在解释中使用了numpy。


我是在将一个literal iterable传递给一个构造函数或函数的上下文中回答这个问题的,超过这个上下文类型就不重要了。如果需要传入可散列参数,则需要一个元组。如果您需要它变异,请传入一个列表(这样您就不会向元组中添加元组,从而使对象的创建成倍增加)。

你的问题的答案是更好的选择在不同的情况下。这是权衡。

从可变的list类型开始,它为将来的扩展预先分配内存:

1
a = np.zeros([2, 3])

它很容易阅读。

反对者:它浪费了记忆,而且性能较差。

接下来是tuple类型,它是不可变的。它不需要为将来的扩展预先分配内存,因为它不能被扩展。

1
b = np.zeros((2, 3))

优点:它使用最少的内存,而且性能更好。

反对者:它的可读性稍差一点。

我的首选是传递元组文本,其中考虑内存,例如,许多人将使用长时间运行的脚本。另一方面,当我使用交互式解释器时,我更喜欢传递列表,因为它们的可读性更高,方括号和圆括号之间的对比便于可视化解析。

您应该只关心函数的性能,其中代码被编译为字节码:

1
2
3
4
>>> min(timeit.repeat('foo()', 'def foo(): return (0, 1)'))
0.080030765042010898
>>> min(timeit.repeat('foo()', 'def foo(): return [0, 1]'))
0.17389221549683498

最后,请注意,性能考虑因素将与其他考虑因素相形见绌。使用Python是为了提高开发速度,而不是为了提高算法实现的速度。如果你使用了一个坏的算法,你的性能会更差。它在许多方面也非常出色。我认为这一点很重要,只要它能改善大量使用的过程,使其免于死于千刀之死。


如果在设计时知道项目的数量(例如坐标、颜色系统),那么我将使用元组,否则使用列表。

如果我正在编写一个接口,我的代码将倾向于检查参数是可引用的还是序列(而不是检查特定类型,除非接口需要特定类型)。我使用collections模块来进行检查——它比检查特定属性更干净。