有什么区别?
元组/列表有哪些优点/缺点?
答案 0 :(得分:965)
除了元组不可变之外,还有一个语义上的区别应该指导它们的使用。元组是异构数据结构(即,它们的条目具有不同的含义),而列表是同构序列。 元组有结构,列表有顺序。
使用这种区别可以使代码更加清晰易懂。
一个例子是一对页面和行号来引用书中的位置,例如:
my_location = (42, 11) # page number, line number
然后,您可以将其用作字典中的键,以存储位置注释。另一方面,列表可用于存储多个位置。当然,人们可能希望在列表中添加或删除位置,因此列表是可变的是有意义的。另一方面,在现有位置添加或删除项目没有意义 - 因此元组是不可变的。
在某些情况下,您可能希望更改现有位置元组中的项目,例如在遍历页面行时。但元组不变性迫使您为每个新值创建一个新的位置元组。这看起来很不方便,但使用这样的不可变数据是价值类型和函数式编程技术的基石,它们具有很大的优势。
关于这个问题有一些有趣的文章,例如: "Python Tuples are Not Just Constant Lists"或"Understanding tuples vs. lists in Python"。官方Python文档also mentions this
“元组是不可变的,通常包含异构序列......”。
在像 Haskell 这样的静态类型语言中,元组中的值通常具有不同的类型,并且元组的长度必须是固定的。在列表中,值都具有相同的类型,并且长度不固定。所以区别非常明显。
最后在Python中有namedtuple,这是有道理的,因为元组已经被认为具有结构。这强调了元组是类和实例的轻量级替代品的想法。
答案 1 :(得分:331)
列表和元组之间的区别
<强>立即强>
someTuple = (1,2)
someList = [1,2]
<强>尺寸强>
a = tuple(range(1000))
b = list(range(1000))
a.__sizeof__() # 8024
b.__sizeof__() # 9088
由于元组操作的尺寸较小,它变得有点快,但在你拥有大量元素之前没有多少提及。
允许的操作
b = [1,2]
b[0] = 3 # [3, 2]
a = (1,2)
a[0] = 3 # Error
这也意味着您无法删除元素或对元组进行排序。 但是,您可以向列表和元组添加新元素,唯一的区别是您将通过添加元素来更改元组的ID
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
<强>用法强>
由于列表是可变的,因此不能用作字典中的键,而可以使用元组。
a = (1,2)
b = [1,2]
c = {a: 1} # OK
c = {b: 1} # Error
<强>可哈希强> 列表是可清洗的,而列表则不是。散列函数返回对象的散列值(如果有的话)。
答案 2 :(得分:190)
如果你去散步,你可以在(x,y)
元组的任何时刻记下你的坐标。
如果您想记录您的旅程,您可以每隔几秒将您的位置附加到列表中。
但是你无法反过来做到这一点。
答案 3 :(得分:73)
关键区别在于元组是不可变的。这意味着一旦创建了元组,就无法更改元组中的值。
因此,如果您需要更改值,请使用List。
对元组的好处:
答案 4 :(得分:31)
列表是可变的;元组不是。
来自docs.python.org/2/tutorial/datastructures.html
元组是不可变的,通常包含异构序列 通过解压缩访问的元素(参见本节后面部分) 或索引(甚至在namedtuples的情况下通过属性)。清单 是可变的,它们的元素通常是同质的 通过遍历列表来访问。
答案 5 :(得分:20)
been mentioned差异主要是语义:人们期望元组和列表代表不同的信息。但这比指南更进一步;一些库实际上根据传递的内容表现不同。以NumPy为例(从another post复制,我要求更多例子):
>>> 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列表和元组中是完全不同的东西。
答案 6 :(得分:18)
列表用于循环,元组用于结构,即"%s %s" %tuple
。
列表通常是同类的,元组通常是异构的。
列表用于可变长度,元组用于固定长度。
答案 7 :(得分:16)
这是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列表和元组的相似之处在于它们都是有序的值集合。除了使用括号&#34; [...,...]&#34;创建列表的浅层差异之外和元组使用括号&#34;(...,...)&#34;,核心技术&#34;用Python语法硬编码&#34;它们之间的区别在于特定元组的元素是不可变的,而列表是可变的(...所以只有元组是可以清除的,并且可以用作字典/散列键!)。这会导致他们能够或不能使用的方式(通过语法强制执行)和人们选择使用它们的方式存在差异(鼓励作为最佳实践,&#39; a posteriori,这就是 smart 程序员所做的事情。当使用元组与使用列表时区分后验的主要区别在于人们对元素顺序的意义。
对于元组,&#39; order&#39;仅仅表示一个特定的结构&#39;持有信息。在第一个字段中找到的值可以很容易地切换到第二个字段,因为每个字段提供跨两个不同维度或比例的值。它们提供不同类型问题的答案,通常具有以下形式:对于给定的对象/主题,它的属性是什么?对象/主体保持不变,属性不同。
对于列表,&#39; order&#39;表示序列或方向性。第二个元素必须在第一个元素之后,因为它基于特定和常见的比例或维度位于第二个位置。这些元素作为一个整体提供,主要提供表格的单个问题的答案,给定属性的,这些对象/主题如何比较?属性保持不变,对象/主题不同
无数的流行文化和程序员都不符合这些差异,有无数人可能会使用沙拉叉作为主菜。在一天结束时,它很好,通常都可以完成工作。
总结一些更精细的细节
<强>相似点:强>
索引,选择和&amp;切片 - 使用括号内的整数值对元组和列表进行索引。因此,如果您想要给定列表或元组的前3个值,则语法将是相同的:
>>> my_list[0:3]
[0,1,2]
>>> my_tuple[0:3]
[a,b,c]
比较&amp;排序 - 两个元组或两个列表都按其第一个元素进行比较,如果存在平局,则由第二个元素进行比较,依此类推。在先前的元素显示出差异之后,不再进一步关注后续元素。
>>> [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
差异: - 先验,根据定义
语法 - 列表使用[],元组使用()
Mutability - 给定列表中的元素是可变的,给定元组中的元素是不可变的。
# 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
哈希表(字典) - 由于哈希表(字典)要求其密钥是可清除的,因此不可变,只有元组可以充当字典键,而不是列表。
#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}
差异 - 后验,使用中
Homo与元素的异构性 - 通常列表对象是同质的,元组对象是异构的。也就是说,列表用于相同类型的对象/主题(如所有总统候选人,或所有歌曲,或所有参赛者),尽管它不是强制的,但元组更多用于异类对象。
循环与结构 - 尽管两者都允许循环(对于my_list中的x ...),但只对列表进行循环才有意义。元组更适合于构造和呈现信息(%s%s居住在%s中是%s,目前是%s%(&#34; John&#34;,&#34; Wayne&#34;,90210,&# 34;演员&#34;&#34;死&#34))
答案 8 :(得分:9)
列表的值可以随时更改,但元组的值无法更改。
优点和缺点取决于用途。如果你有这样一个你永远不想改变的数据,你应该使用元组,否则列表是最好的选择。
答案 9 :(得分:7)
列表旨在是同构序列,而元组是异构数据结构。
答案 10 :(得分:6)
在Python中,提示和列表都是相似的序列类型。
文学语法
我们使用括号()构造元组和方括号
[ ]
以获取新列表。另外,我们可以使用适当类型的调用来获取所需的结构-元组或列表。
someTuple = (4,6)
someList = [2,6]
可变性
组是不可变的,而列表是可变的。这是以下几点的基础。
内存使用量
由于可变性,您需要更多的内存用于列表,而更少的内存用于元组。
扩展
您可以将新元素添加到元组和列表中,唯一的区别是将更改元组的ID(即,我们将有一个新对象)。
哈希
组是可哈希的,列表是不可哈希的。这意味着您可以将元组用作字典中的键。该列表不能用作字典中的键,而可以使用元组
tup = (1,2)
list_ = [1,2]
c = {tup : 1} # ok
c = {list_ : 1} # error
语义
这点更多是关于最佳实践的。您应该将元组用作异构数据结构,而列表则是同质序列。
答案 11 :(得分:4)
正如人们已经在这里回答的那样tuples
是不可变的,而lists
是可变的,但使用元组有一个重要的方面,我们必须记住
如果tuple
中包含list
或dictionary
,即使tuple
本身不可变,也可以更改这些内容。
例如,假设我们有一个包含列表和字典为
的元组my_tuple = (10,20,30,[40,50],{ 'a' : 10})
我们可以将列表的内容更改为
my_tuple[3][0] = 400
my_tuple[3][1] = 500
使新元组看起来像
(10, 20, 30, [400, 500], {'a': 10})
我们也可以将元组内的字典更改为
my_tuple[4]['a'] = 500
这将使整个元组看起来像
(10, 20, 30, [400, 500], {'a': 500})
这是因为list
和dictionary
是对象,这些对象没有改变,而是指向的内容。
因此tuple
保持不变,没有任何异常
答案 12 :(得分:3)
PEP 484 -- Type Hints表示tuple
的元素类型可以单独输入;这样你就可以说Tuple[str, int, float]
;但是list
,List
输入类只能使用一个类型参数:List[str]
,这暗示2的差异确实是前者是异构的,而后者本质上是同质的
此外,标准库主要使用元组作为此类标准函数的返回值,其中C将返回struct
。
答案 13 :(得分:3)
正如人们已经提到的差异一样,我将写有关元组的原因。
为什么首选元组?
小元组的分配优化
为了减少内存碎片并加快分配速度,Python重用了旧的元组。如果一个 元组不再需要,并且少于20个项目,而不是删除 它会永久地将其移至空闲列表。
免费列表分为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
答案 14 :(得分:2)
最重要的区别是时间!当您不想更改列表内的数据时,最好使用元组!这是为什么使用元组的示例!
import timeit
print(timeit.timeit(stmt='[1,2,3,4,5,6,7,8,9,10]', number=1000000)) #created list
print(timeit.timeit(stmt='(1,2,3,4,5,6,7,8,9,10)', number=1000000)) # created tuple
在此示例中,我们执行了两条语句100万次
输出:
0.136621
0.013722200000000018
任何人都可以清楚地注意到时差。
答案 15 :(得分:2)
来自5.3. Tuples and Sequences的文档的方向引用:
尽管元组看起来与列表类似,但它们通常用于不同的情况并用于不同的目的。元组是不可变的,并且通常包含异构序列元素,这些元素可以通过解包(参见本节后面的内容)或索引来访问(甚至是在namedtuples的情况下的属性)。列表是 mutable ,它们的元素通常是同类,并且可以通过迭代访问列表。
答案 16 :(得分:1)
首先,它们都是Python中的非标量对象(也称为复合对象)。
+
连接(当然会创建全新的元组)(3,) # -> (3)
代替(3) # -> 3
[3]
new_array = origin_array[:]
[x**2 for x in range(1,7)]
为您提供
[1,4,9,16,25,36]
(不可读)使用list也可能导致别名错误(两条不同的路径) 指向同一个对象)。
答案 17 :(得分:0)
列表是可变的,元组是不可变的。 请考虑这个例子。
a = ["1", "2", "ra", "sa"] #list
b = ("1", "2", "ra", "sa") #tuple
现在更改list和tuple的索引值。
a[2] = 1000
print a #output : ['1', '2', 1000, 'sa']
b[2] = 1000
print b #output : TypeError: 'tuple' object does not support item assignment.
因此证明以下代码对元组无效,因为我们试图更新一个不允许的元组。
答案 18 :(得分:0)
只是list
vs tuple
响应的快速扩展:
由于动态性质,list
分配的位存储桶比实际所需的内存更多。这样做是为了防止在将来添加额外的项目时进行昂贵的重新分配操作。
另一方面,作为静态的轻量级tuple
对象不会保留存储它们所需的额外内存。
答案 19 :(得分:0)
列表是可变的。而元组是不可变的。在元组中访问带有索引的偏移元素比列表更有意义,因为元素及其索引不能更改。
答案 20 :(得分:0)
除了这里提出的许多其他评论之外,我看到使用元组的好处是它们能够具有不同于列表的不同类型的值的灵活性。
以一个数据库表为例,它为每一列指定了不同的值和类型。一个列表根本无法复制这一点(因为它限制了它可以包含的单一类型的值)而 Tuple 可以有多种不同的类型和值,并且它们的每一列都尊重它们的位置(甚至可以放置在列表中创建您自己的数据库虚拟表示)。
这种灵活性和限制(因为值不能改变)也有它的好处,比如交易数据的传输(或者类似于表格的格式)。您“密封”元组中的数据,防止它在发送保护它之前被修改,因为它的设计目的是:提供不变性。与只读集合相比,这有什么区别?事实上,您可以拥有不同的值类型。
它的应用(因为列表、对象和字典的大量使用)受到限制,人们普遍认为对象模型可以作为更好的选择(在某些情况下确实如此),但是假设您不想要对象模型,因为您更愿意将其与您定义为业务实体的内容分开。那么元组可能会很好地帮助您实现您想要实现的目标。
答案 21 :(得分:-1)
我发现的基本区别是列表是可变的,因为元组是不可变的。元组非常适合不需要更改的计算。
答案 22 :(得分:-1)
列表是可变的,元组是不可变的。可变和不可变的主要区别在于您尝试追加项目时的内存使用情况。
创建变量时,会为变量分配一些固定内存。如果是列表,则分配的内存比实际使用的内存多。例如。如果当前存储器分配是100个字节,当你想要追加第101个字节时,可能会分配另外100个字节(在这种情况下总共200个字节)。
但是,如果您知道不经常添加新元素,那么您应该使用元组。元组分配所需内存的大小,因此可以节省内存,尤其是在使用大块内存时。