>>> t = 12345, 54321, 'hello!'
>>> t[0]
12345
>>> t
(12345, 54321, 'hello!')
>>> # Tuples may be nested:
... u = t, (1, 2, 3, 4, 5)
>>> u
((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
As you see, on output tuples are alway enclosed in parentheses, so that nested tuples are interpreted correctly; they may be input with or without surrounding parentheses, although often parentheses are necessary anyway (if the tuple is part of a larger expression).
如你所见,元组在输出时总是有括号的,以便于正确表达嵌套结构。在输入时可能有或没有括号都可以,不过经常括号都是必须的(如果元组是一个更大的表达式的一部分)。
Tuples have many uses. For example: (x, y) coordinate pairs, employee records from a database, etc. Tuples, like strings, are immutable: it is not possible to assign to the individual items of a tuple (you can simulate much of the same effect with slicing and concatenation, though). It is also possible to create tuples which contain mutable objects, such as lists.
元组有很多用途。例如(x, y)坐标点,数据库中的员工记录等等。元组就像字符串,不可改变:不能给元组的一个独立的元素赋值(尽管你可以通过联接和切片来模仿)。也可以通过包含可变对象来创建元组,例如链表。
A special problem is the construction of tuples containing 0 or 1 items: the syntax has some extra quirks to accommodate these. Empty tuples are constructed by an empty pair of parentheses; a tuple with one item is constructed by following a value with a comma (it is not sufficient to enclose a single value in parentheses). Ugly, but effective. For example:
一个特殊的问题是构造包含零个或一个元素的元组:为了适应这种情况,语法上有一些额外的改变。一对空的括号可以创建空元组;要创建一个单元素元组可以在值后面跟一个逗号(在括号中放入一个单值是不够的)。丑陋,但是有效。例如:
>>> empty = ()
>>> singleton = 'hello', # <-- note trailing comma
>>> len(empty)
0
>>> len(singleton)
1
>>> singleton
('hello',)
The statement t = 12345, 54321, 'hello!'
is an example of tuple packing: the values 12345
, 54321
and 'hello!'
are packed together in a tuple. The reverse operation is also possible:
语句 t = 12345, 54321, 'hello!' 是元组封装(sequence packing)的一个例子:值 12345, 54321 和 'hello!' 被封装进元组。其逆操作可能是这样:
This is called, appropriately enough, sequence unpacking. Sequence unpacking requires that the list of variables on the left have the same number of elements as the length of the sequence. Note that multiple assignment is really just a combination of tuple packing and sequence unpacking!
这个调用被称为序列拆封非常合适。序列拆封要求左侧的变量数目与序列的元素个数相同。要注意的是可变参数(multiple assignment )其实只是元组封装和序列拆封的一个结合!
There is a small bit of asymmetry here: packing multiple values always creates a tuple, and unpacking works for any sequence.
这里有一点不对称:封装多重参数通常会创建一个元组,而拆封操作可以作用于任何序列。
5.4 Dictionaries 字典
Another useful data type built into Python is the dictionary. Dictionaries are sometimes found in other languages as ``associative memories'' or ``associative arrays''. Unlike sequences, which are indexed by a range of numbers, dictionaries are indexed by keys, which can be any immutable type; strings and numbers can always be keys. Tuples can be used as keys if they contain only strings, numbers, or tuples; if a tuple contains any mutable object either directly or indirectly, it cannot be used as a key. You can't use lists as keys, since lists can be modified in place using their append() and extend() methods, as well as slice and indexed assignments.
另一个非常有用的Python内建数据类型是字典。字典在某些语言中可能称为“联合内存”(``associative memories'')或“联合数组”(``associative arrays'')。序列是以连续的整数为索引,与此不同的是,字典以关键字为索引,关键字可以是任意不可变类型,通常用字符串或数值。如果元组中只包含字符串和数字,它可以做为关键字,如果它直接或间接的包含了可变对象,就不能当做关键字。不能用链表做关键字,因为链表可以用它们的append() 和 extend()方法,或者用切片、或者通过检索变量来即时改变。
It is best to think of a dictionary as an unordered set of key: value pairs, with the requirement that the keys are unique (within one dictionary). A pair of braces creates an empty dictionary: {}
. Placing a comma-separated list of key:value pairs within the braces adds initial key:value pairs to the dictionary; this is also the way dictionaries are written on output.
理解字典的最佳方式是把它看做无序的关键字:值 对(key:value pairs)集合,关键字必须是互不相同的(在同一个字典之内)。一对大括号创建一个空的字典:{}
。初始化链表时,在大括号内放置一组逗号分隔的关键字:值对,这也是字典输出的方式。
The main operations on a dictionary are storing a value with some key and extracting the value given the key. It is also possible to delete a key:value pair with del
. If you store using a key that is already in use, the old value associated with that key is forgotten. It is an error to extract a value using a non-existent key.
字典的主要操作是依据关键字来存储和析取值。也可以用 del
来删除关键字:值对。如果你用一个已经存在的关键字存储值,以前为该关键字分配的值就会被遗忘。试图析取从一个不存在的关键字中读取值会导致错误。
The keys() method of a dictionary object returns a list of all the keys used in the dictionary, in random order (if you want it sorted, just apply the sort() method to the list of keys). To check whether a single key is in the dictionary, use the has_key() method of the dictionary.
字典的 keys()方法返回由所有关键字组成的链表,该链表的顺序不定(如果你需要它有序,只能调用关键字链表的sort() 方法)。使用字典的 has_key()方法可以检查字典中是否存在某一关键字。
Here is a small example using a dictionary:
这是一个关于字典应用的小示例:
>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'sape': 4139, 'guido': 4127, 'jack': 4098}
>>> tel['jack']
4098
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'guido': 4127, 'irv': 4127, 'jack': 4098}
>>> tel.keys()
['guido', 'irv', 'jack']
>>> tel.has_key('guido')
True
The dict() constructor builds dictionaries directly from lists of key-value pairs stored as tuples. When the pairs form a pattern, list comprehensions can compactly specify the key-value list.
链表中存储关键字-值对元组的话,字典可以从中直接构造。关键字-值对来自一个模式时,可以用链表推导式简单的表达关键字-值链表。
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'jack': 4098, 'guido': 4127}
>>> dict([(x, x**2) for x in vec]) # use a list comprehension
{2: 4, 4: 16, 6: 36}
5.5 循环技巧 Looping Techniques
When looping through dictionaries, the key and corresponding value can be retrieved at the same time using the iteritems() method.
在字典中循环时,关键字和对应的值可以使用 iteritems()方法同时解读出来。
>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.iteritems():
... print k, v
...
gallahad the pure
robin the brave
When looping through a sequence, the position index and corresponding value can be retrieved at the same time using the enumerate() function.
在序列中循环时,索引位置和对应值可以使用enumerate()函数同时得到。
>>> for i, v in enumerate(['tic', 'tac', 'toe']):
... print i, v
...
0 tic
1 tac
2 toe
To loop over two or more sequences at the same time, the entries can be paired with the zip() function.
同时循环两个或更多的序列,可以使用 zip() 整体解读。
>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
... print 'What is your %s? It is %s.' % (q, a)
...
What is your name? It is lancelot.
What is your quest? It is the holy grail.
What is your favorite color? It is blue.
5.6 深入条件控制 More on Conditions
The conditions used in while
and if
statements above can contain other operators besides comparisons.
用于 while
和 if
语句的条件包括了比较之外的操作符。
The comparison operators in
and not in
check whether a value occurs (does not occur) in a sequence. The operators is
and is not
compare whether two objects are really the same object; this only matters for mutable objects like lists. All comparison operators have the same priority, which is lower than that of all numerical operators.
in
和 not in
比较操作符审核值是否在一个区间之内。操作符 is
is not
和比较两个对象是否相同;这只和诸如链表这样的可变对象有关。所有的比较操作符具有相同的优先级,低于所有的数值操作。
Comparisons can be chained. For example, a < b == c
tests whether a
is less than b
and moreover b
equals c
.
比较操作可以传递。例如 a < b == c
审核是否 a
小于 b
并 b
等于c
。
Comparisons may be combined by the Boolean operators and
and or
, and the outcome of a comparison (or of any other Boolean expression) may be negated with not
. These all have lower priorities than comparison operators again; between them, not
has the highest priority, and or
the lowest, so that A and not B or C
is equivalent to (A and (not B)) or C
. Of course, parentheses can be used to express the desired composition.
比较操作可以通过逻辑操作符 and
和 or
组合,比较的结果可以用 not
来取反义。这些操作符的优先级又低于比较操作符,在它们之中,not
具有最高的优先级, or
优先级最低,所以A and not B or C
等于 (A and (not B)) or C
。当然,表达式可以用期望的方式表示。
The Boolean operators and
and or
are so-called short-circuit operators: their arguments are evaluated from left to right, and evaluation stops as soon as the outcome is determined. For example, if A
and C
are true but B
is false, A and B and C
does not evaluate the expression C
. In general, the return value of a short-circuit operator, when used as a general value and not as a Boolean, is the last evaluated argument.
逻辑操作符 and
和 or
也称作短路操作符:它们的参数从左向右解析,一旦结果可以确定就停止。例如,如果 A
和 C
为真而 B
为假, A and B and C
不会解析 C
。作用于一个普通的非逻辑值时,短路操作符的返回值通常是最后一个变量
It is possible to assign the result of a comparison or other Boolean expression to a variable. For example,
可以把比较或其它逻辑表达式的返回值赋给一个变量,例如:
>>> string1, string2, string3 = '', 'Trondheim', 'Hammer Dance'
>>> non_null = string1 or string2 or string3
>>> non_null
'Trondheim'
Note that in Python, unlike C, assignment cannot occur inside expressions. C programmers may grumble about this, but it avoids a common class of problems encountered in C programs: typing =
in an expression when ==
was intended.
需要注意的是Python与C不同,在表达式内部不能赋值。C 程序员经常对此抱怨,不过它避免了一类在 C 程序中司空见惯的错误:想要在解析式中使 ==
时误用了 =
操作符。
5.7 比较序列和其它类型 Comparing Sequences and Other Types
Sequence objects may be compared to other objects with the same sequence type. The comparison uses lexicographical ordering: first the first two items are compared, and if they differ this determines the outcome of the comparison; if they are equal, the next two items are compared, and so on, until either sequence is exhausted. If two items to be compared are themselves sequences of the same type, the lexicographical comparison is carried out recursively. If all items of two sequences compare equal, the sequences are considered equal. If one sequence is an initial sub-sequence of the other, the shorter sequence is the smaller (lesser) one. Lexicographical ordering for strings uses the ASCII ordering for individual characters. Some examples of comparisons between sequences with the same types:
序列对象可以与相同类型的其它对象比较。比较操作按 字典序 进行:首先比较前两个元素,如果不同,就决定了比较的结果;如果相同,就比较后两个元素,依此类推,直到所有序列都完成比较。如果两个元素本身就是同样类型的序列,就递归字典序比较。如果两个序列的所有子项都相等,就认为序列相等。如果一个序列是另一个序列的初始子序列,较短的一个序列就小于另一个。字符串的字典序按照单字符的 ASCII 顺序。下面是同类型序列之间比较的一些例子:
(1, 2, 3) < (1, 2, 4)
[1, 2, 3] < [1, 2, 4]
'ABC' < 'C' < 'Pascal' < 'Python'
(1, 2, 3, 4) < (1, 2, 4)
(1, 2) < (1, 2, -1)
(1, 2, 3) == (1.0, 2.0, 3.0)
(1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4)
Note that comparing objects of different types is legal. The outcome is deterministic but arbitrary: the types are ordered by their name. Thus, a list is always smaller than a string, a string is always smaller than a tuple, etc. Mixed numeric types are compared according to their numeric value, so 0 equals 0.0, etc.5.1
需要注意的是不同类型的对象比较是合法的。输出结果是确定而非任意的:类型按它们的名字排序。因而,一个链表(list)总是小于一个字符串(string),一个字符串(string)总是小于一个元组(tuple)等等。数值类型比较时会统一它们的数据类型,所以0等于0.0,等等。5.2
Footnotes
- ... etc.5.1
- The rules for comparing objects of different types should not be relied upon; they may change in a future version of the language.
- ...需要注意的是不同类型的对象比较是合法的。输出结果是确定而非任意的:类型按它们的名字排序。因而,一个链表(list)总是小于一个字符串(string),一个字符串(string)总是小于一个元组(tuple)等等。数值类型比较时会统一它们的数据类型,所以0等于0.0,等等。5.2
- 不同类型对象的比较规则不依赖于此,它们有可能会在Python语言的后继版本中改变