为什么我们需要Python中的元组(或任何不可变的数据类型)?
我已经阅读了一些python教程(比如深入python),以及python.org上的语言参考——我不明白为什么该语言需要元组 元组与列表或集合相比没有方法,如果我必须将元组转换为集合或列表才能对它们进行排序,那么首先使用元组有什么意义 不变性 为什么有人关心变量在内存中的位置是否与最初分配时不同?Python中的不变性似乎被过分强调了 在C/C++中,如果我分配一个指针并指向某个有效内存,我不在乎地址在哪里,只要在使用它之前地址不为空 每当我引用那个变量时,我不需要知道指针是否仍然指向原始地址。我只是检查null并使用它(或者不使用) 在Python中,当我分配一个字符串(或元组)并将其分配给x,然后修改该字符串时,为什么我要关心它是否是原始对象?只要变量指向我的数据,这就是最重要的为什么我们需要Python中的元组(或任何不可变的数据类型)?,python,tuples,Python,Tuples,我已经阅读了一些python教程(比如深入python),以及python.org上的语言参考——我不明白为什么该语言需要元组 元组与列表或集合相比没有方法,如果我必须将元组转换为集合或列表才能对它们进行排序,那么首先使用元组有什么意义 不变性 为什么有人关心变量在内存中的位置是否与最初分配时不同?Python中的不变性似乎被过分强调了 在C/C++中,如果我分配一个指针并指向某个有效内存,我不在乎地址在哪里,只要在使用它之前地址不为空 每当我引用那个变量时,我不需要知道指针是否仍然指向原始地址
>>> x='hello'
>>> id(x)
1234567
>>> x='good bye'
>>> id(x)
5432167
x
仍然引用我想要的数据,为什么有人需要关心它的id是相同的还是不同的?有时我们喜欢使用对象作为字典键
值得一提的是,最近的元组(2.6+)增长了index()
和count()
方法,您可以看到关于这方面的一些讨论
$ python -mtimeit '["fee", "fie", "fo", "fum"]'
1000000 loops, best of 3: 0.432 usec per loop
$ python -mtimeit '("fee", "fie", "fo", "fum")'
10000000 loops, best of 3: 0.0563 usec per loop
如果我必须将元组转换为集合或列表才能对它们进行排序,那么首先使用元组有什么意义
在这种特殊情况下,可能没有任何意义。这不是一个问题,因为这不是您考虑使用元组的情况之一。
正如您所指出的,元组是不可变的。具有不可变类型的原因适用于元组:
- 复制效率:与复制不可变对象不同,您可以将其别名(将变量绑定到引用)
- 比较效率:使用引用复制时,可以通过比较位置而不是内容来比较两个变量
- 实习:你最多需要存储一个不可变值的副本
- 不需要在并发代码中同步对不可变对象的访问
- 常量正确性:某些值不允许更改。这(对我来说)是不可变类型的主要原因
另请参见“,”。上面的答案都没有指出元组与列表的真正问题,而许多Python新手似乎并不完全理解元组与列表的关系 元组和列表有不同的用途。列表存储同质数据。您可以而且应该有如下列表:
["Bob", "Joe", "John", "Sam"]
["Billy", "Bob", "Joe", 42]
正确使用列表的原因是因为这些都是同质类型的数据,特别是人名。但请列举如下:
["Bob", "Joe", "John", "Sam"]
["Billy", "Bob", "Joe", 42]
这份名单是一个人的全名和年龄。这不是一种类型的数据。存储该信息的正确方法是在元组或对象中。假设我们有几个:
[("Billy", "Bob", "Joe", 42), ("Robert", "", "Smith", 31)]
元组和列表的不变性和易变性并不是主要区别。列表是相同种类的项目的列表:文件、名称、对象。元组是一组不同类型的对象。它们有不同的用途,许多Python编码人员滥用列表来表示元组的用途
请不要
编辑: 我认为这篇博文解释了为什么我认为这比我做的更好:
a = [1,1,1]
doWork(a)
呼叫方无法保证呼叫后a的值。
但是,
a = (1,1,1)
doWorK(a)
现在,作为调用方或代码的读者,您知道a是相同的。
在这种情况下,您可以复制列表并传递它,但现在您正在浪费周期,而不是使用更具语义意义的语言结构。我一直发现,对于相同的基本数据结构(数组),有两种完全不同的类型是一种笨拙的设计,但在实践中并不是一个真正的问题。(每种语言都有它的缺点,包括Python,但这并不是一个重要的缺点。) 为什么有人关心变量在内存中的位置是否与最初分配时不同?Python中的不变性似乎被过分强调了 这些是不同的事情。易变性与它存储在内存中的位置无关;这意味着它指向的东西不能改变 Python对象在创建后不能更改位置,无论是否可变。(更准确地说,id()的值不能更改——实际上也是一样。)可变对象的内部存储可以更改,但这是一个隐藏的实现细节
>>> x='hello'
>>> id(x)
1234567
>>> x='good bye'
>>> id(x)
5432167
这不是修改(“变异”)变量;是c
>>> a1 = (1,)
>>> a2 = a1
>>> print a2[0]
1
>>> a1 = (2,)
>>> print a2[0]
1
>>> t1 = (1,2)
>>> d1 = { t1 : 'three' }
>>> print d1
{(1,2): 'three'}
>>> t1[0] = 0 ## results in a TypeError, as tuples cannot be modified
>>> t1 = (2,3) ## creates a new tuple, does not modify the old one
>>> print d1 ## as seen here, the dict is still intact
{(1,2): 'three'}
blue= 0, 0, 255
alist= ["red", "green", blue]