有什么不同?
元组/列表的优点/缺点是什么?
list
。; D
有什么不同?
元组/列表的优点/缺点是什么?
list
。; D
Answers:
除了元组是不可变的之外,还有语义上的区别应指导它们的使用。元组是异构数据结构(即,它们的条目具有不同的含义),而列表是同类序列。元组具有结构,列表具有顺序。
使用这种区别可以使代码更加明确和易于理解。
一个示例是成对的页和行号,以成对参考书中的位置,例如:
my_location = (42, 11) # page number, line number
然后,您可以将其用作字典中的键来存储有关位置的注释。另一方面,列表可用于存储多个位置。自然地,人们可能想在列表中添加或删除位置,因此列表是可变的很有意义。另一方面,从现有位置添加或删除项目没有意义-因此,元组是不可变的。
在某些情况下,您可能想更改现有位置元组中的项目,例如在页面的各行中进行迭代时。但是元组不变性迫使您为每个新值创建一个新的位置元组。从表面上看,这似乎很不方便,但是使用这样的不可变数据是值类型和函数编程技术的基石,可以具有很多优点。
关于此问题,有一些有趣的文章,例如“ Python元组不仅仅是常量列表”或“了解Python中的元组与列表”。官方Python文档也提到了这一点
“组是不可变的,并且通常包含一个异类序列...”。
在像Haskell这样的静态类型语言中,元组中的值通常具有不同的类型,并且元组的长度必须固定。在列表中,所有值都具有相同的类型,并且长度不是固定的。因此区别非常明显。
最后,在Python中有一个namedtuple,这很有意义,因为一个元组已经被认为具有结构。这强调了元组是类和实例的轻量级替代方案的思想。
collections.namedtuple
更好collections.record
。例如,在客户记录中交换姓名和地址是没有意义的。实际上,这样做通常是一个错误,元组的不变性阻止您提交。
What would you do with such a list?
,当ppl以缺乏幻想为理由时,我总是不寒而栗。使用混合类型列表非常有用,例如对于某些分层数据结构而言,其中每个列表都由子列表和值元素组成。
列表和元组之间的区别
文字
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
3. Permitted operation
显示元组大小写。我知道通常会先显示成功,然后显示错误,但这使我的头有些混乱。
one_item_list = [a]
,但是one_tuple = (a,)
是对应的元组。注意变量名后的逗号。还要注意two_tuple = (a, b)
。这使我不止一次离开(仍然在Python 3中存在)。
tuple(sorted(the_unsorted_tuple))
如果您去散散步,您可以随时在 (x,y)
元组中。
如果要记录您的旅程,可以每隔几秒钟将您的位置附加到一个列表中。
但您无法做到这一点。
关键区别在于元组是不可变的。这意味着一旦创建元组,就无法更改其值。
因此,如果您需要更改值,请使用列表。
对元组的好处:
frozenset
第三方冻结的dict / tree / etc。类型,但这些都不允许您添加可变元素。(当然,元组只有在其所有元素都可以被哈希的情况下才是可哈希的,这是用通常的EAFP方法处理的,因此d[1, [2]]
将引发TypeError: unhashable type: 'list'
。)
列表是可变的;元组不是。
来自docs.python.org/2/tutorial/datastructures.html
元组是不可变的,通常包含一个异类元素序列,这些元素可以通过拆包(请参阅本节后面的内容)或索引(甚至在命名元组的情况下通过属性)进行访问。列表是可变的,并且它们的元素通常是同类的,并且可以通过遍历列表来访问。
它被提及的差异主要语义:人们期待一个元组和列表来表示不同的信息。但这远远超出了指导原则。有些库实际上根据传递的内容而有所不同。以NumPy为例(从我要求更多示例的另一篇文章中复制):
>>> 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列表和元组中是完全不同的东西。
type(a_list) != type(a_tuple)
,因此分支所基于的任何库代码的type(x)
行为都将有所不同
'%d %d' % [2, 3]
是a TypeError
,因为您正尝试将列表传递给第一个%d
,而不要将任何值传递给第二个%d
。(但是,也有一些反例,例如max
…)
列表用于循环,元组用于结构,即"%s %s" %tuple
。
列表通常是同质的,元组通常是异类的。
列表用于可变长度,元组用于固定长度。
这是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语法进行硬编码”之间的差异是特定元组的元素是不可变的,而列表是可变的(...因此,只有元组是可哈希的,并且可以用作字典/哈希键!)。这就导致了它们的使用方式或不使用方式的差异(通过语法先验地实现)以及人们选择使用它们的方式上的差异(鼓励作为“最佳实践”,后验,这就是智能程序员所做的事情)。 人们赋予元素顺序。
对于元组,“顺序”仅表示存储信息的特定“结构”。在第一个字段中找到的值可以很容易地切换到第二个字段,因为每个值都提供跨两个不同维度或比例的值。它们为不同类型的问题提供答案,并且通常采用以下形式:对于给定的对象/对象,其属性是什么?对象/对象保持不变,属性不同。
对于列表,“顺序”表示顺序或方向。第二个元素必须位于第一个元素之后,因为它基于特定且通用的比例或维度位于第二位。这些元素是一个整体,并且通常针对一个给定属性的形式为单个问题提供答案,对于给定的属性,这些对象/对象如何比较?属性保持不变,对象/主题不同。
有无数流行文化的人和不符合这些差异的程序员的例子,有无数人可能在主菜上使用色叉。一天结束后,一切都很好,通常都可以完成工作。
总结一些更好的细节
相似之处:
索引,选择和切片 -元组和列表都使用括号内的整数值进行索引。因此,如果要给定列表或元组的前三个值,语法将是相同的:
>>> my_list[0:3]
[0,1,2]
>>> my_tuple[0:3]
[a,b,c]
比较和排序 -两个元组或两个列表都通过它们的第一个元素进行比较,如果有平局,则通过第二个元素进行比较,依此类推。在较早的元素显示出不同之后,不再关注后续元素。
>>> [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
区别: -先验,根据定义
语法 -列表使用[],元组使用()
可变性 -给定列表中的元素是可变的,给定元组中的元素不是可变的。
# 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}
差异-后验用法
元素的均质性与异质性-通常,列表对象是同质的,而元组对象是异质的。也就是说,列表用于相同类型的对象/对象(例如所有总统候选人,所有歌曲或所有跑步者),而虽然不是强制的,但元组更多地用于异构对象。
循环与结构-尽管两者都允许循环(对于my_list中的x,...),但实际上对于列表而言才有意义。元组更适合于结构化和呈现信息(驻留在%s中的%s%s是%s,当前是%s%(“ John”,“ Wayne”,90210,“ Actor”,“ Dead”))
元组和列表在Python中似乎都是相似的序列类型。
文字语法
我们使用括号()构造元组和方括号
[ ]
以获取新列表。另外,我们可以使用适当类型的调用来获取所需的结构-元组或列表。
someTuple = (4,6)
someList = [2,6]
变异性
元组是不可变的,而列表是可变的。这是以下几点的基础。
内存使用情况
由于可变性,您需要更多的内存用于列表,而更少的内存用于元组。
延伸
您可以将新元素添加到元组和列表中,唯一的区别是将更改元组的ID(即,我们将有一个新的对象)。
散列
元组可散列,而列表则不可。这意味着您可以将元组用作字典中的键。该列表不能用作字典中的键,而可以使用元组
tup = (1,2)
list_ = [1,2]
c = {tup : 1} # ok
c = {list_ : 1} # error
语义学
这一点是关于最佳实践的。您应该将元组用作异构数据结构,而列表则是同质序列。
正如人们已经在这里回答的那样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
遗物毫无例外地保持不变
该PEP 484 -类型提示说,该类型的元素tuple
可以单独输入; 这样你可以说Tuple[str, int, float]
; 但是list
,随着List
键入类可以采取仅一种类型的参数:List[str]
,这提示了2的差异确实是,前者是异质的,而后者本质上是均匀的。
另外,标准库通常使用元组作为C会返回a的标准函数的返回值struct
。
正如人们已经提到的差异一样,我将写有关元组的原因。
为什么首选元组?
小元组的分配优化
为了减少内存碎片并加快分配速度,Python重用了旧的元组。如果不再需要一个元组,并且元组少于20个,而不是将其永久删除,Python会将其移至空闲列表。
一个空闲列表分为20组,其中每个组代表长度为n的0至20之间的元组列表。每个组最多可以存储2000个元组。第一个(零)组仅包含一个元素,代表一个空的元组。
>>> 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
首先,它们都是Python中的非标量对象(也称为复合对象)。
+
(当然会创建全新的元组)(3,) # -> (3)
而不是(3) # -> 3
[3]
new_array = origin_array[:]
[x**2 for x in range(1,7)]
给您
[1,4,9,16,25,36]
(不可读)使用列表可能还会导致混淆错误(指向同一对象的两个不同路径)。
列表是可变的,元组是不可变的。只要考虑这个例子。
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.
因此证明了以下代码对元组无效,因为我们试图更新一个元组,这是不允许的。
列表是可变的,元组是不可变的。可变项和不可变项之间的主要区别是在尝试附加项目时的内存使用情况。
创建变量时,会将一些固定内存分配给该变量。如果是列表,则分配的内存将大于实际使用的内存。例如,如果当前内存分配为100字节,则当您要追加第101个字节时,可能会另外分配100个字节(在这种情况下,总共为200个字节)。
但是,如果您知道不经常添加新元素,则应使用元组。元组精确分配所需的内存大小,从而节省了内存,尤其是在使用大容量内存块时。