在Python中,什么时候应该使用列表,什么时候使用元组?

有时候你没有选择,比如你有选择

"hello %s you are %s years old" % x

那么x一定是一个元组。

但如果我是设计API并选择数据类型的人,那么指导原则是什么?


当前回答

它必须是可变的吗?使用列表。 它必须是不可变的吗?使用元组。

否则,这是一个选择的问题。

对于异构对象的集合(如地址分解为名称、街道、城市、州和zip),我更喜欢使用元组。它们总是可以很容易地提升为命名元组。

同样地,如果集合将被迭代,我更喜欢使用列表。如果它只是一个容器,以容纳多个对象为一个,我更喜欢元组。

其他回答

但如果我是设计API并选择数据类型的人,那么指导原则是什么?

对于输入参数,最好接受最通用的接口来满足您的需要。它很少只是一个元组或列表——更多的是序列,可切片甚至可迭代。Python的duck类型通常是免费的,除非显式检查输入类型。除非不可避免,否则不要那样做。

对于你生成的数据(输出参数),只返回对你来说最方便的,例如,返回你保留的任何数据类型或你的helper函数返回的任何数据类型。

要记住的一件事是避免返回作为你状态一部分的列表(或任何其他可变的)。

class ThingsKeeper
    def __init__(self):
        self.__things = []

    def things(self):
        return self.__things  #outside objects can now modify your state

    def safer(self):
        return self.__things[:]  #it's copy-on-write, shouldn't hurt performance

有一种很强的文化,即元组用于异构集合,类似于在C中使用结构体的目的,而列表用于同构集合,类似于使用数组的目的。但我从来没有把这个问题与其他答案中提到的可变性问题联系起来。可变性很重要(您实际上不能更改元组),而同质性并不是强制的,因此似乎不是一个有趣得多的区别。

它必须是可变的吗?使用列表。 它必须是不可变的吗?使用元组。

否则,这是一个选择的问题。

对于异构对象的集合(如地址分解为名称、街道、城市、州和zip),我更喜欢使用元组。它们总是可以很容易地提升为命名元组。

同样地,如果集合将被迭代,我更喜欢使用列表。如果它只是一个容器,以容纳多个对象为一个,我更喜欢元组。

我相信(我几乎不精通Python),主要的区别是元组是不可变的(赋值后不能在适当位置更改),而列表是可变的(可以追加、更改、减去等)。

我倾向于元组在赋值后不应该改变而列表可以改变。

列表相对于元组的一个次要但值得注意的优点是列表往往更易于移植。标准工具不太可能支持元组。例如,JSON没有元组类型。YAML是这样的,但是它的语法与它的列表语法相比是丑陋的,而列表语法是相当不错的。

在这些情况下,您可能希望在内部使用元组,然后将其转换为列表作为导出过程的一部分。另外,为了保持一致性,您可能希望在任何地方都使用列表。