元组实战——转换,方法和不可更改性 | 第二部分 类型与操作 —— 第 9 章: 元组,文件和其他 |《学习 python:强大的面向对象编程(第 5 版)》| python 技术论坛-江南app体育官方入口
除了字面量语法的差异,元组操作(表9-1中的中间行)与字符串和列表的操作是一样的。唯一值得注意的区别是:当应用到元组时,
,*
和切片操作返回新的元组;元组不提供在字符串,列表,字典中看到的同样方法。比如,如果想排序元组,通常必须先将其转换为列表获得排序方法调用的权限并让其成为一个可变对象,或使用更新的接收任何序列对象(和其它可迭代对象——在第4章介绍的一个属于,将在本书的下一部分更正式的讲述)的sorted
内置函数:
>>> t = ('cc', 'aa', 'dd', 'bb')
>>> tmp = list(t) # make a list from a tuple's items
>>> tmp.sort() # sort the list
>>> tmp
['aa', 'bb', 'cc', 'dd']
>>> t = tuple(tmp) # make a tuple from the list's items
>>> t
('aa', 'bb', 'cc', 'dd')
>>> sorted(t) # or use the sorted built-in, and save two steps
['aa', 'bb', 'cc', 'dd']
在这里,list
和 tuple
内置函数被用来将对象转换为列表然后再转回元组;其实,这两个调用都创建了新对象,但最终效果开起来像一个转换。
列表comprehensions也能被用来转换元组。比如,下例从元组创建列表,在此过程中对每一项都加了20:
>>> t = (1, 2, 3, 4, 5)
>>> l = [x 20 for x in t]
>>> l
[21, 22, 23, 24, 25]
列表comprehensions其实是序列操作——它们总是构建新列表,但可能被用来迭代任何序列对象,包括元组、字符串和其它列表。本书稍后将看到:它们甚至适用于一些物理上不是存储序列的东西——任何可迭代的对象都可以,包括文件,它被自动逐行读取。考虑到这个情况,它们被称为迭代工具更好些。
虽然元组没有同列表和字符串一样的方法,但它们从2.6和3.0版本开始就有自己的两个方法——index
和count
方法和列表中的效果是一样的,但它们是为元组对象定义的:
>>> t = (1, 2, 3, 2, 4, 2) # tuple methods in 2.6, 3.0, and later
>>> t.index(2) # offset of first appearance of 2
1
>>> t.index(2, 2) # offset of appearance after offset 2
3
>>> t.count(2) # how many 2s are there?
3
在2.6和3.0之前,元组根本没有方法——这是不可变类型的一个老的python约定,由于字符串的实用性,它在数年前就被违反了,最近数字和元组也违反了。
还有,注意关于元组不可改变性的规则只应用于元组本身的顶层,而非其内容。比如,在一个元组中的一个列表,可以和往常一样被修改:
>>> t = (1, [2, 3], 4)
>>> t[1] = 'spam' # this fails: can't change tuple itself
typeerror: object doesn't support item assignment
>>> t[1][0] = 'spam' # this works: can change mutables inside
>>> t
(1, ['spam', 3], 4)
对大多数程序来说,这个一层深度的可不改变性对常见的元组角色是足够的。这巧合地将我们带到了下一节。