必须使用元组的情况

tar*_*ish 20 python tuples list

在Python中,我知道列表和元组之间的唯一区别是"列表是可变的,但元组不是".但据我所知,这取决于编码人员是否愿意冒险.

所以我想知道是否有任何情况下必须使用列表上的元组.无法通过列表完成但可以使用元组完成的事情?

Ott*_*ger 30

您可以使用元组作为字典中的键并将元组插入集合中:

>>> {}[tuple()] = 1
>>> {}[list()] = 1 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
Run Code Online (Sandbox Code Playgroud)

这基本上是一个tuple可以清洗的结果而一个list不是:

>>> hash(list())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> hash(tuple())
3527539
Run Code Online (Sandbox Code Playgroud)

  • 只需确保在包含它的元组插入set/dict后不修改哈希计算中使用的字段.这与将可变类型放入集合/ dicts中时的规则相同,但是间接的额外层(以及由元组引起的混淆是"不可变的")使得发现它不那么明显. (4认同)
  • @tarashish你可以为任何类定义一个`__hash __()`函数 (2认同)
  • @tarashish:内置的Python类型按照惯例是可变的或可散列的.但是,您可以为任何类型添加`__hash __()`方法.诀窍在于,如果`__hash __()`方法依赖于可变字段,则对象的哈希码可能会随时间而变化.应该不惜一切代价避免这种情况,因为这意味着您可以创建一个对象位于"dict"中的情况,但是由于对象的字段已更改,因此查找该键失败.由于它容易混淆且容易出错,因此避免在可变类型中添加`__hash __()`函数是一种好习惯. (2认同)

mgi*_*son 13

@Otto的答案非常好.我唯一需要补充的是,当你打开第三方扩展时,你真的需要查阅文档.某些函数/方法可能需要一种或另一种数据类型(或根据您使用的数据类型而具有不同的结果).一个例子是使用元组/列表来索引numpy数组:

import numpy as np
a=np.arange(50)
a[[1,4,8]] #array([1, 4, 8])
a[(1,4,8)] #IndexError
Run Code Online (Sandbox Code Playgroud)

编辑

此外,快速计时测试表明,元组创建比列表创建快得多:

import timeit
t=timeit.timeit('[1,2,3]',number=10000000)
print (t)
t=timeit.timeit('(1,2,3)',number=10000000)
print (t)
Run Code Online (Sandbox Code Playgroud)

这是很好的记住.换句话说,做:

for num in (8, 15, 200):
    pass
Run Code Online (Sandbox Code Playgroud)

代替:

for num in [8, 15, 200]:
    pass
Run Code Online (Sandbox Code Playgroud)