python:列表和元组之间的区别是什么?

有什么区别呢?

元组/列表的优点/缺点是什么?


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

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

例如,一本书中引用位置的页码和行号对,例如:

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

然后,您可以使用它作为字典中的键来存储位置上的注释。另一方面,列表可以用来存储多个位置。当然,您可能想要从列表中添加或删除位置,所以列表是可变的是有意义的。另一方面,从现有位置添加或删除项没有意义——因此元组是不可变的。

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

关于这个问题有一些有趣的文章。"Python元组不仅仅是常量列表"或"理解Python中的元组与列表"。官方Python文档也提到了这一点

"Tuples are immutable, and usually contain an heterogeneous sequence ...".

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

最后是Python中的namedtuple,这很有意义,因为元组应该已经具有结构。这强调了元组是类和实例的轻量级替代。


列表和元组之间的区别

文字

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

大小

1
2
3
4
5
a = tuple(range(1000))
b = list(range(1000))

a.__sizeof__() # 8024
b.__sizeof__() # 9088

由于元组操作的大小更小,它会变得更快一些,但在拥有大量元素之前,没有太多需要提及的内容。

允许操作

1
2
3
4
5
b    = [1,2]  
b[0] = 3       # [3, 2]

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

这也意味着您不能删除元素或对元组排序。但是,您可以向列表和元组添加新元素,惟一的区别是您将通过添加元素来更改元组的id

1
2
3
4
5
6
7
8
9
10
11
a     = (1,2)
b     = [1,2]  

id(a)          # 140230916716520
id(b)          # 748527696

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

id(a)          # 140230916878160
id(b)          # 748527696

使用

由于列表是可变的,所以不能在字典中用作键,而可以使用元组。

1
2
3
4
5
a    = (1,2)
b    = [1,2]

c = {a: 1}     # OK
c = {b: 1}     # Error

Hashable元组是可哈希的,而列表不是。哈希函数返回对象的哈希值(如果有)。

Hashability of list and tuple.


如果您出去散步,您可以在(x,y)元组中随时记录您的坐标。

如果你想记录你的旅程,你可以每隔几秒钟就在一个列表中添加你的位置。

但你不能反过来做。


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

如果你需要改变值,使用列表。

元组的好处:

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


列表是可变的;元组。

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

Tuples are immutable, and usually contain an heterogeneous sequence of
elements that are accessed via unpacking (see later in this section)
or indexing (or even by attribute in the case of namedtuples). Lists
are mutable, and their elements are usually homogeneous and are
accessed by iterating over the list.


前面已经提到,这种差异主要是语义上的:人们期望元组和列表表示不同的信息。但这不仅仅是一个指导方针;一些库实际上根据它们传递的内容而有不同的行为。以NumPy为例(从另一篇我要求更多例子的文章中复制):

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> import numpy as np
>>> a = np.arange(9).reshape(3,3)
>>> a
array([[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列表和元组中是完全不同的东西。


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

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

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


这是Python列表的一个例子:

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

这是Python元组的一个例子:

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

Python列表和元组相似之处在于它们都是值的有序集合。除了使用方括号创建列表的细微差别之外,"[…,……"和使用括号的元组"(…,……)",它们之间的核心技术"用Python语法硬编码"的区别在于,特定元组的元素是不可变的,而列表是可变的(…因此,只有元组是可hashable的,并且可以用作字典/散列键!)这导致了在如何使用它们(语法强制执行)和人们如何选择使用它们(鼓励作为"最佳实践",这是一个后验,这是聪明的程序员所做的)方面的差异。区分何时使用元组和何时使用列表的主要区别在于人们赋予元素顺序的意义。

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

对于列表,"order"表示序列或方向性。第二个元素必须在第一个元素之后,因为它基于特定的、常见的比例或维度位于第2位。元素被视为一个整体,并且主要提供一个问题的答案,通常是表单的一个问题,对于给定的属性,这些对象/主题如何比较?属性保持不变,对象/主题不同。

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

来总结一些细节

相似之处:

重复——元组和列表都允许重复

索引、选择,切片——元组和列表索引都使用方括号内的整数值。所以,如果你想要一个给定列表或元组的前三个值,语法应该是一样的:

1
2
3
4
>>> my_list[0:3]
[0,1,2]
>>> my_tuple[0:3]
[a,b,c]

比较,排序——两个元组或两个列表都通过它们的第一个元素进行比较,如果存在平局,则通过第二个元素进行比较,以此类推。在较早的元素显示出差异之后,不再进一步注意后续的元素。

1
2
3
4
>>> [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

差异:-根据定义,这是先验的

语法-列表使用[],元组使用()

可变性——给定列表中的元素是可变的,而给定元组中的元素不是可变的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 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

Hashtables (dictionary)——由于Hashtables (dictionary)要求其键是可hashable的,因此是不可变的,所以只有元组可以充当字典键,而不是列表。

#Lists CAN'T act as keys for hashtables(dictionaries)
>>> my_dict = {[a,b,c]:"some value


list的值可以随时更改,但是元组的值不能更改。

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


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


列表和元组之间的差异

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

文字语法

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

1
2
someTuple = (4,6)
someList  = [2,6]

可变性

元组是不可变的,而列表是可变的。这一点是下列各项的基础。

内存使用情况

由于可变性,列表需要更多内存,元组需要更少内存。

扩展

您可以向元组和列表添加一个新元素,唯一的区别是元组的id将被更改(即,我们将有一个新对象)。

哈希

元组是可哈希的,而列表不是。这意味着您可以在字典中使用元组作为键。列表不能用作字典中的键,而元组可以用作

1
2
3
4
5
tup      = (1,2)
list_    = [1,2]

c = {tup   : 1}     # ok
c = {list_ : 1}     # error

语义

这一点更多的是关于最佳实践。您应该使用元组作为异构数据结构,而列表是同质序列。


PEP 484——Type tips表示tuple元素的类型可以单独键入;所以你可以说Tuple[str, int, float];但是一个带有List类型类的list只能接受一个类型参数:List[str],这暗示了这两种类型的区别实际上是前者是异构的,而后者本质上是同构的。

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


5.3文档中的方向引用。元组和序列:

Though tuples may seem similar to lists, they are often used in different situations and for different purposes. Tuples are immutable, and usually contain a heterogeneous sequence of elements that are accessed via unpacking (see later in this section) or indexing (or even by attribute in the case of namedtuples). Lists are mutable, and their elements are usually homogeneous and are accessed by iterating over the list.


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

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

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

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

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

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

这使得新的元组看起来像什么

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

我们也可以将tuple中的字典更改为

1
my_tuple[4]['a'] = 500

哪一个会使整个元组看起来像

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

之所以会发生这种情况,是因为listdictionary是对象,而这些对象并没有改变,而是其指向的内容。

因此,tuple保持不变,没有任何例外


First of all, they both are the non-scalar objects (also known as a compound objects) in Python.

Tuples, ordered sequence of elements (which can contain any object with no aliasing issue)

Immutable (tuple, int, float, str)
Concatenation using +(当然会创建全新的元组)索引切片Singleton (3,) # -> (3)代替了(3) # -> 3列表(其他语言中的数组),值的有序序列可变的单例[3]克隆new_array = origin_array[:]列表理解[x**2 for x in range(1,7)]给你[1,4,9,16,25,36](非可读)

使用list还可能导致别名错误(两个不同的路径)指向同一个物体)。


列表是可变的,元组是不可变的。考虑一下这个例子。

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

现在更改list和tuple的索引值。

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

因此证明下面的代码对于元组是无效的,因为我们试图更新一个元组,这是不允许的。


我发现的基本区别是列表是可变的,而元组是不可变的。元组对于不需要更改的计算是很好的。


列表是可变的,元组是不可变的。可变和不可变之间的主要区别是,当您试图添加一个项时,内存的使用情况。

当您创建一个变量时,会为该变量分配一些固定的内存。如果是列表,则分配的内存比实际使用的内存多。例如,如果当前内存分配为100个字节,当您想追加第101个字节时,可能会分配另外100个字节(在本例中为200个字节)。

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