列表是可变序列,具有许多方法(包括变异和非变异的方法),通常用作通用容器(它们的项可以是任何类型的对象,尽管有时认为列表最好具有相同类型或等效使用的项)。
元组是不可变序列,具有非常少的方法(所有非变异特殊方法),通常在需要不可变性以将容器用作集合中的项或字典中的键时使用(尽管项目也必须是不可变的——例如,字符串,数字或其他嵌套元组才能正常工作)。它们的项可以是任何类型的对象,对于元组来说,具有许多不同且独特类型的项是完全正常的。
有些情况下,元组或列表都可以很好地使用,在这些情况下,元组稍微小一些且构建速度更快的事实可以用于支持选择元组。例如,当函数需要返回多个结果时,最常规的做法是使用元组。
return fee, fie, foo, fum
return [fee, fie, foo, fum]
即,返回一个包含四个项目的列表——除了(性能方面的小收益),“返回元组”这个常见的习惯用法还解决了多个结果返回的问题,这些结果通常不是相同的,也不能互换,因此从风格上讲,使用列表可能被认为是更加可疑的选择。
tuple
的一个有用变体是它的子类型 collections.namedtuple (需要 Python 2.6 或更高版本),它允许您通过名称(使用属性语法)以及索引(正常方式)访问项目。例如,在模块顶部进行 import collections
后,上述 return
语句可能会变成...
freturn = collections.namedtuple('freturn', 'fee fie foo fum')
def f():
...
return freturn(fee, fie, foo, fum)
现在,f()
的调用者可以像以前一样使用其返回值作为元组,但会获得更好的选择,例如...
r = f()
print r.fie
print r[1]
collections.namedtuple
创建的命名元组子类与直接使用元组相比基本没有额外开销,或者如文档所述,它们“轻量级且不需要比普通元组更多的内存。”set
,那么为什么答案中要提到它呢?是的,set
和frozenset
与list
和tuple
之间有可比较的差异。虽然我使用set
的频率远不及list
和tuple
,但它们是我工具箱中不可或缺的工具。 - Nathan Ernst列表是可变的(可以更改),元组是不可变的。典型用途:听起来有些陈词滥调,但当你需要更改值时使用列表。由于其不可变性,元组通常会更有效率(除非您像使用列表一样频繁复制它们...)
在阅读了Python内置类型文档之后,我创建了下面的表格来展示六个可迭代容器之间的主要区别。
<pre>
Container Notation Index [n:m] Mutable Hashable
========= ========== =========== ======= ========
String ' ' or " " position Immutable Yes
Range range(,,) position Immutable Yes
Tuple (,) position Immutable Yes
List [,] position Yes No
Set {,} No Yes No
Dict {k:v,k:v} by key Yes No
</pre>
搜索集合和字典更快,因为它们是哈希的而不是顺序的,因此与大小无关。元组和列表相同,除了元组是不可变的,方法比列表少,因此不支持项目赋值来更改其内容。但是,可以连接两个元组以实现“追加”功能,即t1 += t2
。
由于只有不可变序列类型支持hash(),因此列表、集合和字典不能用作字典键。下面很容易看到这一点,其中'a'是一个包含int、float、str、range和tuple等异构不可变键类型的字典序列:
>>> a
{range(2, 5, 2): 'range', 3: 15, 4.5: 16, 'llmjxm': 'c', -555: 666, -4.5: -25, (5, 6, 7): 'blue', 'abc3': 215, (1, 2, 3): 'red'}
>>> for item in a.keys():
... print(item, '\t\t==>>', a[item])
...
range(2, 5, 2) ==>> range
3 ==>> 15
4.5 ==>> 16
llmjxm ==>> c
-555 ==>> 666
-4.5 ==>> -25
(5, 6, 7) ==>> blue
abc3 ==>> 215
(1, 2, 3) ==>> red
>>>
如果使用可变类型的键,则会导致 TypeError 错误:
>>> a[{5}] = 56
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'
>>> a[[5]] = 56
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> a[{5:6}] = 56
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
>>> a[-555] = 666
>>>