列表vs元组,什么时候使用每个?

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

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

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

那么x一定是一个元组。

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

445631 次浏览

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

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

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

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

  • 元组比列表快。如果你定义了一组常量值,而你所要做的就是遍历它,那么使用元组而不是列表。

  • 如果您对不需要更改的数据进行“写保护”,则会使代码更安全。使用元组而不是列表就像使用一个隐含的断言语句,该数据是常量,并且需要特殊的思想(和特定的函数)来覆盖它。

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

来源:深入了解Python 3

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

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

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

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

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

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

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

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

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

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

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

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

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

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