507

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

有时您别无选择,例如,如果您有

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

那么 x 必须是一个元组。

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

4

7 回答 7

811

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

  1. 您不能将元素添加到元组。元组没有附加或扩展方法。
  2. 您不能从元组中删除元素。元组没有删除或弹出方法。
  3. 您可以在元组中找到元素,因为这不会更改元组。
  4. 您还可以使用in运算符检查元组中是否存在元素。

  • 元组比列表快。如果您要定义一组常量值,并且您要做的只是遍历它,请使用元组而不是列表。

  • 如果您“写保护”不需要更改的数据,它会使您的代码更安全。使用元组而不是列表就像有一个隐含的断言声明该数据是恒定的,并且需要特殊的想法(和特定的函数)来覆盖它。

  • 一些元组可以用作字典键(特别是包含不可变值的元组,如字符串、数字和其他元组)。列表永远不能用作字典键,因为列表不是不可变的。

资料来源:深入 Python 3

于 2009-11-10T14:53:41.487 回答
263

元组用于异类集合的文化很浓厚,类似于您struct在 C 中使用 s 的内容,而列表用于同类集合,类似于您使用数组的内容。但是我从来没有将这与其他答案中提到的可变性问题完全吻合。可变性对它有影响(实际上你不能改变一个元组),而同质性并没有被强制执行,因此似乎是一个不那么有趣的区别。

于 2009-11-10T15:02:09.317 回答
88

我相信(而且我几乎不精通 Python)主要区别在于元组是不可变的(分配后不能就地更改)而列表是可变的(您可以追加、更改、减去等)。

所以,我倾向于让我的元组在分配后不应该改变的东西,我列出可以改变的东西。

于 2009-11-10T14:53:36.877 回答
51

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

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

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

同样,如果要迭代集合,我更喜欢列表。如果它只是一个容器来容纳多个对象,我更喜欢一个元组。

于 2009-11-10T15:01:14.973 回答
19

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

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

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

元组中的第一个位置是在用户玩游戏时显示给用户的选项,第二个位置是该选项进入的页面的键,这对于所有页面都是一致的。

元组也比列表更节省内存,尽管我不确定这种好处何时会变得明显。

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

于 2009-11-10T15:15:12.613 回答
11

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

对于输入参数,最好接受最通用的接口来满足您的需求。它很少只是一个元组或列表——更常见的是它是序列、可切片甚至可迭代的。Python 的鸭子类型通常是免费的,除非你明确地检查输入类型。除非绝对不可避免,否则不要这样做。

对于您生成的数据(输出参数),只需返回对您最方便的数据,例如返回您保留的任何数据类型或您的辅助函数返回的任何数据。

要记住的一件事是避免返回属于您的状态的列表(或任何其他可变的),例如

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
于 2009-11-10T15:46:15.553 回答
4

与元组相比,列表的一个次要但显着的优势是列表往往更易于移植。标准工具不太可能支持元组。例如,JSON 没有元组类型。YAML 可以,但它的语法与它的列表语法相比是丑陋的,这非常好。

在这些情况下,您可能希望在内部使用元组,然后在导出过程中转换为列表。或者,您可能希望在任何地方都使用列表以保持一致性。

于 2014-05-09T21:05:07.547 回答