列表和元组有什么区别?

元组/列表之间有什么区别,它们的优点/缺点是什么?

449005 次浏览

列表是可变的;元组不是。

docs.python.org/2/tutorial/datastructures.html

元组是不可变的,通常包含一个异构的通过解包访问的元素(见本节后面)或索引(甚至在命名元组的情况下按属性)。列表是可变的,它们的元素通常是同质的通过遍历列表访问。

关键区别在于元组是不可变的。这意味着一旦创建了元组,您就无法更改元组中的值。

因此,如果您需要更改值,请使用List。

元组的好处:

  1. 性能略有改善。
  2. 由于元组是不可变的,它可以用作字典中的键。
  3. 如果你不能改变它,其他人也不能,也就是说你不需要担心任何API函数等在没有被要求的情况下改变你的元组。

除了元组是不可变的之外,还有一个语义上的区别应该指导它们的使用。元组是异构数据结构(即,它们的条目有不同的含义),而列表是同构序列。元组有结构,列表有顺序。

使用这种区别使代码更加明确和可理解。

一个例子是将页码和行号对引用书籍中的位置,例如:

my_location = (42, 11)  # page number, line number

然后,您可以将其用作字典中的键来存储位置的注释。另一方面,列表可用于存储多个位置。自然,人们可能希望从列表中添加或删除位置,因此列表是可变的是有道理的。另一方面,从现有位置添加或删除项目是没有意义的-因此元组是不可变的。

在某些情况下,你可能想更改现有位置元组中的项目,例如在迭代页面的行时。但是元组的不变性迫使你为每个新值创建一个新的位置元组。从表面上看,这似乎很不方便,但使用像这样的不可变数据是值类型和函数式编程技术的基石,这可能有很大的优势。

关于这个问题有一些有趣的文章,例如“Python元组不仅仅是常量列表”“了解Python中的元组与列表”。官方Python留档还提到这

“元组是不可变的,通常包含一个异构序列……”。

在像haskell这样的静态类型语言中,元组中的值通常具有不同的类型,并且元组的长度必须固定。在列表中,值都具有相同的类型,长度不固定。所以差异非常明显。

最后是Python中的命名元组,这是有道理的,因为元组已经应该有结构。这强调了元组是类和实例的轻量级替代品的想法。

如果你去散步,你可以在任何时刻在(x,y)元组中记下你的坐标。

如果您想记录您的旅程,您可以每隔几秒钟将您的位置附加到列表中。

但你不能反过来做。

列表是同构序列,而元组是异构数据结构。

列表用于循环,元组用于结构,即"%s %s" %tuple

列表通常是同质的,元组通常是异质的。

列表用于可变长度,元组用于固定长度。

列表的值可以随时更改,但元组的值不能更改。

优点和缺点取决于使用。如果您有这样一个您永远不想更改的数据,那么您应该使用元组,否则列表是最好的选择。

0是差异在很大程度上是语义上的:人们期望元组和列表来表示不同的信息。但这不仅仅是指导方针;一些库实际上根据传递的内容表现不同。以NumPy为例(从另一篇文章复制,我要求提供更多示例):

>>> import numpy as np>>> a = np.arange(9).reshape(3,3)>>> aarray([[0, 1, 2],[3, 4, 5],[6, 7, 8]])>>> idx = (1,1)>>> a[idx]4>>> idx = [1,1]>>> a[idx]array([[3, 4, 5],[3, 4, 5]])

关键是,虽然NumPy可能不是标准库的一部分,但它是一个主要 Python库,并且在NumPy中列表和元组是完全不同的东西。

list和tuple的区别

  1. 字面

    someTuple = (1,2)someList  = [1,2]
  2. Size

    a = tuple(range(1000))b = list(range(1000))
    a.__sizeof__() # 8024b.__sizeof__() # 9088

    由于元组操作的大小较小,它变得有点快,但在你有大量元素之前,没有那么多可提及的。

  3. 允许的操作

    b    = [1,2]b[0] = 3       # [3, 2]
    a    = (1,2)a[0] = 3       # Error

    这也意味着您不能删除元素或对元组进行排序。但是,您可以向列表和元组添加新元素,唯一的区别是,由于元组是不可变的,您不是真的添加元素,而是创建一个新元组,因此id将更改

    a     = (1,2)b     = [1,2]
    id(a)          # 140230916716520id(b)          # 748527696
    a   += (3,)    # (1, 2, 3)b   += [3]     # [1, 2, 3]
    id(a)          # 140230916878160id(b)          # 748527696
  4. Usage

    As a list is mutable, it can't be used as a key in a dictionary, whereas a tuple can be used.

    a    = (1,2)b    = [1,2]
    c = {a: 1}     # OKc = {b: 1}     # Error

列表是可变的,元组是不可变的。可变和不可变的主要区别在于尝试附加项目时的内存使用情况。

当您创建变量时,会为该变量分配一些固定内存。如果它是一个列表,则分配的内存多于实际使用的内存。例如,如果当前内存分配是100字节,当您想追加第101字节时,可能会再分配100字节(在这种情况下总共200字节)。

但是,如果您知道您不经常添加新元素,那么您应该使用元组。元组准确分配所需内存的大小,因此节省内存,特别是当您使用大块内存时。

这是Python列表的一个示例:

my_list = [0,1,2,3,4]top_rock_list = ["Bohemian Rhapsody","Kashmir","Sweet Emotion", "Fortunate Son"]

这是一个Python元组的例子:

my_tuple = (a,b,c,d,e)celebrity_tuple = ("John", "Wayne", 90210, "Actor", "Male", "Dead")

Python列表和元组的相似之处在于它们都是值的有序集合。除了使用括号“[…,…]”创建列表和使用括号“(…,…)”创建元组的浅层区别之外,它们之间的核心技术“Python语法硬编码”区别在于特定元组的元素是不可变的,而列表是可变的(…所以只有元组是可散列的,可以用作字典/哈希键!)。这导致了如何使用或不使用元组的差异(通过语法先验强制执行)以及人们选择如何使用它们的差异(鼓励作为“最佳实践”,后验,这是智能程序员所做的)。

对于元组来说,“顺序”仅仅意味着用于保存信息的特定“结构”。在第一个字段中找到的值可以很容易地切换到第二个字段,因为每个字段都提供了两个不同维度或尺度的值。它们提供不同类型问题的答案,通常是以下形式:对于一个给定的对象/主题,它的属性是什么?对象/主题保持不变,属性不同。

对于列表,'order'表示序列或方向。第二个元素必须在那之后第一个元素,因为它基于特定和常见的尺度或维度位于第二位。这些元素被视为一个整体,主要提供对一个典型形式的问题的答案,对于给定的属性,这些对象/主题如何比较?属性保持不变,对象/主题不同。

在流行文化中,有无数的人和程序员不符合这些差异的例子,也有无数的人可能会在主菜中使用沙拉叉。在一天结束的时候,这很好,两者通常都能完成工作。

来总结一些细节

相似之处:

  1. 重复-元组和列表都允许重复
  2. 索引、选择和切片-元组和列表都使用括号内的整数值进行索引。因此,如果您想要给定列表或元组的前3个值,语法将是相同的:

    >>> my_list[0:3][0,1,2]>>> my_tuple[0:3][a,b,c]
  3. Comparing & Sorting - Two tuples or two lists are both compared by their first element, and if there is a tie, then by the second element, and so on. No further attention is paid to subsequent elements after earlier elements show a difference.

    >>> [0,2,0,0,0,0]>[0,0,0,0,0,500]True>>> (0,2,0,0,0,0)>(0,0,0,0,0,500)True

Differences: - A priori, by definition

  1. Syntax - Lists use [], tuples use ()

  2. Mutability - Elements in a given list are mutable, elements in a given tuple are NOT mutable.

    # Lists are mutable:>>> top_rock_list['Bohemian Rhapsody', 'Kashmir', 'Sweet Emotion', 'Fortunate Son']>>> top_rock_list[1]'Kashmir'>>> top_rock_list[1] = "Stairway to Heaven">>> top_rock_list['Bohemian Rhapsody', 'Stairway to Heaven', 'Sweet Emotion', 'Fortunate Son']
    # Tuples are NOT mutable:>>> celebrity_tuple('John', 'Wayne', 90210, 'Actor', 'Male', 'Dead')>>> celebrity_tuple[5]'Dead'>>> celebrity_tuple[5]="Alive"Traceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: 'tuple' object does not support item assignment
  3. Hashtables (Dictionaries) - As hashtables (dictionaries) require that its keys are hashable and therefore immutable, only tuples can act as dictionary keys, not lists.

    #Lists CAN'T act as keys for hashtables(dictionaries)>>> my_dict = {[a,b,c]:"some value"}Traceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: unhashable type: 'list'
    #Tuples CAN act as keys for hashtables(dictionaries)>>> my_dict = {("John","Wayne"): 90210}>>> my_dict{('John', 'Wayne'): 90210}

Differences - A posteriori, in usage

  1. Homo vs. Heterogeneity of Elements - Generally list objects are homogenous and tuple objects are heterogeneous. That is, lists are used for objects/subjects of the same type (like all presidential candidates, or all songs, or all runners) whereas although it's not forced by), whereas tuples are more for heterogenous objects.

  2. Looping vs. Structures - Although both allow for looping (for x in my_list...), it only really makes sense to do it for a list. Tuples are more appropriate for structuring and presenting information (%s %s residing in %s is an %s and presently %s % ("John","Wayne",90210, "Actor","Dead"))

首先,它们都是Python中的非标量对象(也称为复合对象)。

  • 元组,元素的有序序列(可以包含任何对象,没有混淆现象)
    • 不可变(元组,int,浮点数,str)
    • 使用+连接(当然会创建全新的元组)
    • 索引
    • 切片
    • 单例(3,) # -> (3)而不是(3) # -> 3
  • 列表(其他语言中的数组),有序的值序列
    • 可变
    • 单例[3]
    • 克隆new_array = origin_array[:]
    • 列表理解[x**2 for x in range(1,7)]给你[1,4,9,16,25,36](不可读)

使用list也可能导致混淆现象bug(两个不同的路径指向同一个对象)。

PEP 484-类型提示tuple的元素类型可以单独类型;所以你可以说Tuple[str, int, float];但是listList类型类只能接受一个类型参数:List[str],这暗示了2的区别在于前者是异构的,而后者本质上是同质的。

此外,标准库主要使用元组作为标准函数的返回值,其中C将返回struct

列表是可变的,元组是不可变的。看看这个例子

a = ["1", "2", "ra", "sa"]    #listb = ("1", "2", "ra", "sa")    #tuple

现在更改列表和元组的索引值。

a[2] = 1000print a     #output : ['1', '2', 1000, 'sa']b[2] = 1000print b     #output : TypeError: 'tuple' object does not support item assignment.

因此证明以下代码对元组无效,因为我们尝试更新元组,这是不允许的。

5.3.元组和序列留档的方向报价:

尽管元组看起来类似于列表,但它们通常用于不同的情况和不同的目的。元组是不可变,通常包含异质序列的元素,这些元素通过拆包(参见本节后面的内容)或索引(甚至在命名元组的情况下通过属性)访问。列表是可变,它们的元素通常是同质,并由迭代通过列表访问。

正如人们已经在这里回答的那样,tuples是不可变的,而lists是可变的,但是我们必须记住使用元组的一个重要方面

如果tuple内部包含listdictionary,即使tuple本身是不可变的,也可以更改它们。

例如,假设我们有一个包含列表和字典的元组

my_tuple = (10,20,30,[40,50],{ 'a' : 10})

我们可以将列表的内容更改为

my_tuple[3][0] = 400my_tuple[3][1] = 500

这使得新的元组看起来像

(10, 20, 30, [400, 500], {'a': 10})

我们还可以将元组中的字典更改为

my_tuple[4]['a'] = 500

这将使整个元组看起来像

(10, 20, 30, [400, 500], {'a': 500})

发生这种情况是因为listdictionary是对象,这些对象没有改变,而是它指向的内容。

所以tuple保持不变,没有任何例外

list和tuple的区别

元组和列表在Python中都是看似相似的序列类型。

  1. 字面语法

    我们使用括号()来构造元组和方括号[ ]来获取新列表。此外,我们可以使用适当类型的调用来获取所需的结构-元组或列表。

    someTuple = (4,6)someList  = [2,6]
  2. Mutability

    Tuples are immutable, while lists are mutable. This point is the base the for the following ones.

  3. Memory usage

    Due to mutability, you need more memory for lists and less memory for tuples.

  4. Extending

    You can add a new element to both tuples and lists with the only difference that the id of the tuple will be changed (i.e., we’ll have a new object).

  5. Hashing

    Tuples are hashable and lists are not. It means that you can use a tuple as a key in a dictionary. The list can't be used as a key in a dictionary, whereas a tuple can be used

    tup      = (1,2)list_    = [1,2]
    c = {tup   : 1}     # okc = {list_ : 1}     # error
  6. Semantics

    This point is more about best practice. You should use tuples as heterogeneous data structures, while lists are homogenous sequences.

正如人们已经提到的差异,我将写为什么元组。

为什么元组是首选?

小元组的分配优化

为了减少内存碎片并加速分配,Python重用旧的元组。如果一个元组不再需要,并且只有不到20个项目而不是删除它永久Python将其移动到一个自由列表。

一个自由列表被分成20组,每组代表一个长度n在0到20之间的元组列表。每个组可以存储到2 000个元组。第一个(零)组仅包含1个元素和表示一个空元组。

>>> a = (1,2,3)>>> id(a)4427578104>>> del a>>> b = (1,2,4)>>> id(b)4427578104

在上面的例子中,我们可以看到a和b具有相同的id。即因为我们立即占用了一个被破坏的元组免费列表。

列表分配优化

由于列表可以修改,Python不使用与元组相同的优化。但是,Python列表也有一个自由列表,但它仅用于空列表对象。如果空列表被GC删除或收集,则可以以后再用

>>> a = []>>> id(a)4465566792>>> del a>>> b = []>>> id(b)4465566792

来源:https://rushter.com/blog/python-lists-and-tuples/

为什么元组比列表有效?->https://stackoverflow.com/a/22140115

只是对listvstuple响应的快速扩展:

  • 由于动态特性,list分配的位存储桶比实际所需的内存多。这样做是为了防止将来附加额外项目时代价高昂的重新分配操作。

  • 另一方面,作为静态的轻量级tuple对象,不会保留存储它们所需的额外内存。

最重要的区别是时间!当你不想改变列表里面的数据时最好使用元组!下面是为什么使用元组的例子!

import timeitprint(timeit.timeit(stmt='[1,2,3,4,5,6,7,8,9,10]', number=1000000)) #created listprint(timeit.timeit(stmt='(1,2,3,4,5,6,7,8,9,10)', number=1000000)) # created tuple

在这个例子中,我们100万次执行这两个语句

输出:

0.1366210.013722200000000018

任何人都可以清楚地注意到时差。

列表是可变的。而元组是不可变的。在元组中使用索引访问偏移元素比列表更有意义,因为元素及其索引不能更改。

除了在这里提出的许多其他评论之外,我在使用元组中看到的好处是它们能够灵活地拥有不同类型的值,不喜欢列表。

例如,一个数据库表为每一列指定了不同的值和类型。列表根本无法复制它(因为它限制了它可以包含的值的单一类型),而元组可以有多个不同的类型和值,并为每一列尊重它们的位置(甚至可以放置在创建您自己的数据库虚拟表示的列表中)。

这种灵活性和限制(因为值不能更改)也有它的好处,比如对于事务数据的传输(或者说类似于表的格式)。你在元组中“密封”数据,防止它在发送前被修改,因为它的设计目的是提供不变性。这与只读集合有什么区别?你可以有不同的值类型。

它的应用(因为列表、对象和字典的大量使用)受到了限制,人们通常认为对象模型是更好的选择(在某些情况下确实如此),但是假设你不想要对象模型,因为你更喜欢将它与你定义为业务实体的东西分开。那么元组可能会在你试图实现的事情上很好地为你服务。

换句话说,TUPLES用于存储元素组,其中组的内容/成员不会改变,而LISTS用于存储元素组,其中组的成员可以改变。

例如,如果我想将网络的IP存储在一个变量中,最好使用元组,因为IP是固定的。像这样my_ip = ('192.168.0.15', 33, 60)。然而,如果我想存储我将在未来6个月访问的地方的IP组,那么我应该使用LIST,因为我将不断更新并向组添加新IP。像这样

places_to_visit = [('192.168.0.15', 33, 60),('192.168.0.22', 34, 60),('192.168.0.1', 34, 60),('192.168.0.2', 34, 60),('192.168.0.8', 34, 60),('192.168.0.11', 34, 60)]