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

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

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

那么x一定是一个元组。

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


当前回答

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

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

其他回答

元组本质上是固定大小的,而列表是动态的。 换句话说,元组是不可变的,而列表是可变的。

你不能在元组中添加元素。元组没有追加或扩展方法。 不能从元组中删除元素。元组没有删除或弹出方法。 您可以在元组中找到元素,因为这不会改变元组。 还可以使用in操作符检查元组中是否存在元素。


Tuples are faster than lists. If you're defining a constant set of values and all you're ever going to do with it is iterate through it, use a tuple instead of a list. It makes your code safer if you “write-protect” data that does not need to be changed. Using a tuple instead of a list is like having an implied assert statement that this data is constant, and that special thought (and a specific function) is required to override that. Some tuples can be used as dictionary keys (specifically, tuples that contain immutable values like strings, numbers, and other tuples). Lists can never be used as dictionary keys, because lists are mutable.

来源:深入了解Python 3

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

但如果我是设计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

您需要决定的第一件事是数据结构是否需要可变。如前所述,列表是可变的,元组不是。这也意味着元组可以用于字典键,而列表不能。

根据我的经验,元组通常用于顺序和位置有意义且一致的地方。例如,在为“选择你自己的冒险游戏”创建数据结构时,我选择使用元组而不是列表,因为元组中的位置是有意义的。下面是该数据结构的一个例子:

pages = {'foyer': {'text' : "some text", 
          'choices' : [('open the door', 'rainbow'),
                     ('go left into the kitchen', 'bottomless pit'),
                     ('stay put','foyer2')]},}

元组中的第一个位置是在用户玩游戏时显示给他们的选择,第二个位置是选择指向的页面的键,这对所有页面都是一致的。

元组的内存效率也比列表高,不过我不确定这种好处什么时候会显现出来。

也可以查看Think Python中关于列表和元组的章节。

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

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