5. Data Structures
5. 数据结构
This chapter describes some things you've learned about already in more detail, and adds some new things as well.本章将详细介绍一些您已经了解的内容,并添加了一些新内容。
5.1. More on Lists
5.1. 列表的更多特性
The list data type has some more methods. Here are all of the methods of list objects:列表数据类型还有很多的方法。这里是列表对象方法的清单:
list.append(x)
list.append(x)
Add an item to the end of the list. Equivalent to "a[len(a):] =list.extend(iterable)
[x]".
在列表的末尾添加一个元素。相当于 "a[len(a):] = [x]" 。list.extend(iterable)
Extend the list by appending all the items from the iterable.list.insert(i, x)
Equivalent to "a[len(a):] = iterable".
使用可迭代对象中的所有元素来扩展列表。相当于 "a[len(a):] =list.insert(i, x)
iterable" 。
Insert an item at a given position. The first argument is thelist.remove(x)
index of the element before which to insert, so "a.insert(0, x)"
inserts at the front of the list, and "a.insert(len(a), x)" is
equivalent to "a.append(x)".
在给定的位置插入一个元素。第一个参数是要插入的元素的索引,所以list.remove(x)
"a.insert(0, x)" 插入列表头部, "a.insert(len(a), x)" 等同于
"a.append(x)" 。
Remove the first item from the list whose value is equal to *x*.list.pop([i])
It raises a "ValueError" if there is no such item.
移除列表中第一个值为 *x* 的元素。如果没有这样的元素,则抛出list.pop([i])
"ValueError" 异常。
Remove the item at the given position in the list, and return it.list.clear()
If no index is specified, "a.pop()" removes and returns the last
item in the list. (The square brackets around the *i* in the
method signature denote that the parameter is optional, not that
you should type square brackets at that position. You will see
this notation frequently in the Python Library Reference.)
删除列表中给定位置的元素并返回它。如果没有给定位置,"a.pop()" 将会list.clear()
删除并返回列表中的最后一个元素。( 方法签名中 *i* 两边的方括号表示
这个参数是可选的,而不是要你输入方括号。你会在 Python 参考库中经常
看到这种表示方法)。
Remove all items from the list. Equivalent to "del a[:]".list.index(x[, start[, end]])
删除列表中所有的元素。相当于 "del a[:]" 。list.index(x[, start[, end]])
Return zero-based index in the list of the first item whose valuelist.count(x)
is equal to *x*. Raises a "ValueError" if there is no such item.
返回列表中第一个值为 *x* 的元素的从零开始的索引。如果没有这样的元素list.count(x)
将会抛出 "ValueError" 异常。
The optional arguments *start* and *end* are interpreted as in the
slice notation and are used to limit the search to a particular
subsequence of the list. The returned index is computed relative
to the beginning of the full sequence rather than the *start*
argument.
可选参数 *start* 和 *end* 是切片符号,用于将搜索限制为列表的特定子
序列。返回的索引是相对于整个序列的开始计算的,而不是 *start* 参数。
Return the number of times *x* appears in the list.list.sort(key=None, reverse=False)
返回元素 *x* 在列表中出现的次数。list.sort(key=None, reverse=False)
Sort the items of the list in place (the arguments can be used forlist.reverse()
sort customization, see "sorted()" for their explanation).
对列表中的元素进行排序(参数可用于自定义排序,解释请参见 "sorted()"list.reverse()
)。
Reverse the elements of the list in place.list.copy()
反转列表中的元素。list.copy()
Return a shallow copy of the list. Equivalent to "a[:]".列表方法示例:
返回列表的一个浅拷贝。相当于 "a[:]" 。An example that uses most of the list methods:
>>> fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']You might have noticed that methods like "insert", "remove" or "sort" that only modify the list have no return value printed -- they return the default "None". [1] This is a design principle for all mutable data structures in Python.
>>> fruits.count('apple')
2
>>> fruits.count('tangerine')
0
>>> fruits.index('banana')
3
>>> fruits.index('banana', 4) # Find next banana starting a position 4
6
>>> fruits.reverse()
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange']
>>> fruits.append('grape')
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange', 'grape']
>>> fruits.sort()
>>> fruits
['apple', 'apple', 'banana', 'banana', 'grape', 'kiwi', 'orange', 'pear']
>>> fruits.pop()
'pear'
你可能已经注意到,像 "insert" ,"remove" 或者 "sort" 方法,只修改列表,没有打印出返回值——它们返回默认值 "None" 。[1] 这是Python中所有可变数据结构的设计原则。
Another thing you might notice is that not all data can be sorted or compared. For instance, "[None, 'hello', 10]" doesn't sort because integers can't be compared to strings and None can't be compared to other types. Also, there are some types that don't have a defined ordering relation. For example, "3+4j < 5+7j" isn't a valid comparison.
Another thing you might notice is that not all data can be sorted orcompared. For instance, "[None, 'hello', 10]" doesn't sort becauseintegers can't be compared to strings and None can't be compared toother types. Also, there are some types that don't have a definedordering relation. For example, "3+4j < 5+7j" isn't a validcomparison.
5.1.1. Using Lists as Stacks
5.1.1. 列表作为栈使用
The list methods make it very easy to use a list as a stack, where the last element added is the first element retrieved ("last-in, first- out"). To add an item to the top of the stack, use "append()". To retrieve an item from the top of the stack, use "pop()" without an explicit index. For example:列表方法使得列表作为堆栈非常容易,最后一个插入,最先取出(“后进先出”)。要添加一个元素到堆栈的顶端,使用 "append()" 。要从堆栈顶部取出一个元素,使用 "pop()" ,不用指定索引。例如
>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> stack
[3, 4]
5.1.2. Using Lists as Queues
5.1.2. 列表作为队列使用
It is also possible to use a list as a queue, where the first element added is the first element retrieved ("first-in, first-out"); however, lists are not efficient for this purpose. While appends and pops from the end of list are fast, doing inserts or pops from the beginning of a list is slow (because all of the other elements have to be shifted by one).列表也可以用作队列,其中先添加的元素被最先取出 (“先进先出”);然而列表用作这个目的相当低效。因为在列表的末尾添加和弹出元素非常快,但是在列表的开头插入或弹出元素却很慢 (因为所有的其他元素都必须移动一位)。
To implement a queue, use "collections.deque" which was designed to have fast appends and pops from both ends. For example:
若要实现一个队列, "collections.deque" 被设计用于快速地从两端操作。例如
>>> from collections import deque
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry") # Terry arrives
>>> queue.append("Graham") # Graham arrives
>>> queue.popleft() # The first to arrive now leaves
'Eric'
>>> queue.popleft() # The second to arrive now leaves
'John'
>>> queue # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])
5.1.3. List Comprehensions
5.1.3. 列表推导式
List comprehensions provide a concise way to create lists. Common applications are to make new lists where each element is the result of some operations applied to each member of another sequence or iterable, or to create a subsequence of those elements that satisfy a certain condition.列表推导式提供了一个更简单的创建列表的方法。常见的用法是把某种操作应用于序列或可迭代对象的每个元素上,然后使用其结果来创建列表,或者通过满足某些特定条件元素来创建子序列。
For example, assume we want to create a list of squares, like:
例如,假设我们想创建一个平方列表,像这样
>>> squares = []Note that this creates (or overwrites) a variable named "x" that still exists after the loop completes. We can calculate the list of squares without any side effects using:
>>> for x in range(10):
... squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
注意这里创建(或被重写)的名为 "x" 的变量在for循环后仍然存在。我们可以计算平方列表的值而不会产生任何副作用
squares = list(map(lambda x: x**2, range(10)))or, equivalently:
或者,等价于
squares = [x**2 for x in range(10)]which is more concise and readable.
上面这种写法更加简洁易读。
A list comprehension consists of brackets containing an expression followed by a "for" clause, then zero or more "for" or "if" clauses. The result will be a new list resulting from evaluating the expression in the context of the "for" and "if" clauses which follow it. For example, this listcomp combines the elements of two lists if they are not equal:
列表推导式的结构是由一对方括号所包含的以下内容:一个表达式,后面跟一个"for" 子句,然后是零个或多个 "for" 或 "if" 子句。 其结果将是一个新列表,由对表达式依据后面的 "for" 和 "if" 子句的内容进行求值计算而得出。 举例来说,以下列表推导式会将两个列表中不相等的元素组合起来:
>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]and it's equivalent to:
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
而它等价于
>>> combs = []Note how the order of the "for" and "if" statements is the same in both these snippets.
>>> for x in [1,2,3]:
... for y in [3,1,4]:
... if x != y:
... combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
注意在上面两个代码片段中, "for" 和 "if" 的顺序是相同的。
If the expression is a tuple (e.g. the "(x, y)" in the previous example), it must be parenthesized.
如果表达式是一个元组(例如上面的 "(x, y)"),那么就必须加上括号
>>> vec = [-4, -2, 0, 2, 4]List comprehensions can contain complex expressions and nested functions:
>>> # create a new list with the values doubled
>>> [x*2 for x in vec]
[-8, -4, 0, 4, 8]
>>> # filter the list to exclude negative numbers
>>> [x for x in vec if x >= 0]
[0, 2, 4]
>>> # apply a function to all the elements
>>> [abs(x) for x in vec]
[4, 2, 0, 2, 4]
>>> # call a method on each element
>>> freshfruit = [' banana', ' loganberry ', 'passion fruit ']
>>> [weapon.strip() for weapon in freshfruit]
['banana', 'loganberry', 'passion fruit']
>>> # create a list of 2-tuples like (number, square)
>>> [(x, x**2) for x in range(6)]
[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]
>>> # the tuple must be parenthesized, otherwise an error is raised
>>> [x, x**2 for x in range(6)]
File "", line 1, in
[x, x**2 for x in range(6)]
^
SyntaxError: invalid syntax
>>> # flatten a list using a listcomp with two 'for'
>>> vec = [[1,2,3], [4,5,6], [7,8,9]]
>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
列表推导式可以使用复杂的表达式和嵌套函数
>>> from math import pi
>>> [str(round(pi, i)) for i in range(1, 6)]
['3.1', '3.14', '3.142', '3.1416', '3.14159']
5.1.4. Nested List Comprehensions
5.1.4. 嵌套的列表推导式
The initial expression in a list comprehension can be any arbitrary expression, including another list comprehension.列表推导式中的初始表达式可以是任何表达式,包括另一个列表推导式。
Consider the following example of a 3x4 matrix implemented as a list of 3 lists of length 4:
考虑下面这个 3x4的矩阵,它由3个长度为4的列表组成
>>> matrix = [The following list comprehension will transpose rows and columns:
... [1, 2, 3, 4],
... [5, 6, 7, 8],
... [9, 10, 11, 12],
... ]
下面的列表推导式将交换其行和列
>>> [[row[i] for row in matrix] for i in range(4)]As we saw in the previous section, the nested listcomp is evaluated in the context of the "for" that follows it, so this example is equivalent to:
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
如上节所示,嵌套的列表推导式是基于跟随其后的 "for" 进行求值的,所以这个例子等价于:
>>> transposed = []which, in turn, is the same as:
>>> for i in range(4):
... transposed.append([row[i] for row in matrix])
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
反过来说,也等价于
>>> transposed = []In the real world, you should prefer built-in functions to complex flow statements. The "zip()" function would do a great job for this use case:
>>> for i in range(4):
... # the following 3 lines implement the nested listcomp
... transposed_row = []
... for row in matrix:
... transposed_row.append(row[i])
... transposed.append(transposed_row)
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
实际应用中,你应该会更喜欢使用内置函数去组成复杂的流程语句。 "zip()"函数将会很好地处理这种情况
>>> list(zip(*matrix))See Unpacking Argument Lists for details on the asterisk in this line.
[(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]
关于本行中星号的详细说明,参见 解包参数列表。
5.2. The "del" statement
5.2. "del" 语句
There is a way to remove an item from a list given its index instead of its value: the "del" statement. This differs from the "pop()" method which returns a value. The "del" statement can also be used to remove slices from a list or clear the entire list (which we did earlier by assignment of an empty list to the slice). For example:有一种方式可以从列表按照给定的索引而不是值来移除一个元素: 那就是 "del"语句。 它不同于会返回一个值的 "pop()" 方法。 "del" 语句也可以用来从列表中移除切片或者清空整个列表(我们之前用过的方式是将一个空列表赋值给指定的切片)。 例如:
>>> a = [-1, 1, 66.25, 333, 333, 1234.5]"del" can also be used to delete entire variables:
>>> del a[0]
>>> a
[1, 66.25, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.25, 1234.5]
>>> del a[:]
>>> a
[]
"del" 也可以被用来删除整个变量
>>> del aReferencing the name "a" hereafter is an error (at least until another value is assigned to it). We'll find other uses for "del" later.
此后再引用 "a" 时会报错(直到另一个值被赋给它)。我们会在后面了解到"del" 的其他用法。
5.3. Tuples and Sequences
5.3. 元组和序列
We saw that lists and strings have many common properties, such as indexing and slicing operations. They are two examples of sequence data types (see Sequence Types --- list, tuple, range). Since Python is an evolving language, other sequence data types may be added. There is also another standard sequence data type: the tuple.我们看到列表和字符串有很多共同特性,例如索引和切片操作。他们是 序列数据类型(参见 序列类型 --- list, tuple, range)中的两种。随着 Python语言的发展,其他的序列类型也会被加入其中。这里介绍另一种标准序列类型:元组。
A tuple consists of a number of values separated by commas, for instance:
一个元组由几个被逗号隔开的值组成,例如
>>> t = 12345, 54321, 'hello!'As you see, on output tuples are always 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). It is not possible to assign to the individual items of a tuple, however it is possible to create tuples which contain mutable objects, such as lists.
>>> 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))
>>> # Tuples are immutable:
... t[0] = 88888
Traceback (most recent call last):
File "", line 1, in
TypeError: 'tuple' object does not support item assignment
>>> # but they can contain mutable objects:
... v = ([1, 2, 3], [3, 2, 1])
>>> v
([1, 2, 3], [3, 2, 1])
如你所见,元组在输出时总是被圆括号包围的,以便正确表示嵌套元组。输入时圆括号可有可无,不过经常会是必须的(如果这个元组是一个更大的表达式的一部分)。给元组中的一个单独的元素赋值是不允许的,当然你可以创建包含可变对象的元组,例如列表。
Though tuples may seem similar to lists, they are often used in different situations and for different purposes. Tuples are immutable, and usually contain a heterogeneous sequence of elements that are accessed via unpacking (see later in this section) or indexing (or even by attribute in the case of "namedtuples"). Lists are mutable, and their elements are usually homogeneous and are accessed by iterating over the list.
虽然元组可能看起来与列表很像,但它们通常是在不同的场景被使用,并且有着不同的用途。元组是 immutable (不可变的),其序列通常包含不同种类的元素,并且通过解包(这一节下面会解释)或者索引来访问(如果是"namedtuples" 的话甚至还可以通过属性访问)。列表是 mutable (可变的),并且列表中的元素一般是同种类型的,并且通过迭代访问。
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:
一个特殊的问题是构造包含0个或1个元素的元组:为了适应这种情况,语法有一些额外的改变。空元组可以直接被一对空圆括号创建,含有一个元素的元组可以通过在这个元素后添加一个逗号来构建(圆括号里只有一个值的话不够明确)。丑陋,但是有效。例如
>>> empty = ()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:
>>> singleton = 'hello', # <-- note trailing comma
>>> len(empty)
0
>>> len(singleton)
1
>>> singleton
('hello',)
语句 "t = 12345, 54321, 'hello!'" 是 元组打包 的一个例子:值"12345", "54321" 和 "'hello!'" 被打包进元组。其逆操作也是允许的
>>> x, y, z = tThis is called, appropriately enough, sequence unpacking and works for any sequence on the right-hand side. Sequence unpacking requires that there are as many variables on the left side of the equals sign as there are elements in the sequence. Note that multiple assignment is really just a combination of tuple packing and sequence unpacking.
这被称为 序列解包 也是很恰当的,因为解包操作的等号右侧可以是任何序列。序列解包要求等号左侧的变量数与右侧序列里所含的元素数相同。注意可变参数其实也只是元组打包和序列解包的组合。
5.4. Sets
5.4. 集合
Python also includes a data type for sets. A set is an unordered collection with no duplicate elements. Basic uses include membership testing and eliminating duplicate entries. Set objects also support mathematical operations like union, intersection, difference, and symmetric difference.Python也包含有 集合 类型。集合是由不重复元素组成的无序的集。它的基本用法包括成员检测和消除重复元素。集合对象也支持像 联合,交集,差集,对称差分等数学运算。
Curly braces or the "set()" function can be used to create sets. Note: to create an empty set you have to use "set()", not "{}"; the latter creates an empty dictionary, a data structure that we discuss in the next section.
花括号或 "set()" 函数可以用来创建集合。注意:要创建一个空集合你只能用"set()" 而不能用 "{}",因为后者是创建一个空字典,这种数据结构我们会在下一节进行讨论。
Here is a brief demonstration:
以下是一些简单的示例:
>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket) # show that duplicates have been removed
{'orange', 'banana', 'pear', 'apple'}
>>> 'orange' in basket # fast membership testing
True
>>> 'crabgrass' in basket
False
>>> # Demonstrate set operations on unique letters from two words
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a # unique letters in a
{'a', 'r', 'b', 'c', 'd'}
>>> a - b # letters in a but not in b
{'r', 'd', 'b'}
>>> a | b # letters in a or b or both
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b # letters in both a and b
{'a', 'c'}
>>> a ^ b # letters in a or b but not both
{'r', 'd', 'b', 'm', 'z', 'l'}
Similarly to list comprehensions, set comprehensions are also supported: 类似于 列表推导式,集合也支持推导式形式
>>> a = {x for x in 'abracadabra' if x not in 'abc'}
>>> a
{'r', 'd'}
5.5. Dictionaries
5.5. 字典
Another useful data type built into Python is the dictionary (see Mapping Types --- dict). 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 index assignments, slice assignments, or methods like "append()" and "extend()".另一个非常有用的 Python 內置数据类型是 字典 (参见 映射类型 --- dict)。字典在其他语言里可能会被叫做 联合内存 或 联合数组。与以连续整数为索引的序列不同,字典是以 关键字 为索引的,关键字可以是任意不可变类型,通常是字符串或数字。如果一个元组只包含字符串、数字或元组,那么这个元组也可以用作关键字。但如果元组直接或间接地包含了可变对象,那么它就不能用作关键字。列表不能用作关键字,因为列表可以通过索引、切片或"append()" 和 "extend()" 之类的方法来改变。
It is best to think of a dictionary as a 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.
理解字典的最好方式,就是将它看做是一个 键: 值 对的集合,键必须是唯一的(在一个字典中)。一对花括号可以创建一个空字典:"{}" 。另一种初始化字典的方式是在一对花括号里放置一些以逗号分隔的键值对,而这也是字典输出的方式。
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" 来删除一个键值对。如果你使用了一个已经存在的关键字来存储值,那么之前与这个关键字关联的值就会被遗忘。用一个不存在的键来取值则会报错。
Performing "list(d)" on a dictionary returns a list of all the keys used in the dictionary, in insertion order (if you want it sorted, just use "sorted(d)" instead). To check whether a single key is in the dictionary, use the "in" keyword.
对一个字典执行 "list(d)" 将返回包含该字典中所有键的列表,按插入次序排列 (如需其他排序,则要使用 "sorted(d)")。要检查字典中是否存在一个特定键,可使用 "in" 关键字。
Here is a small example using a dictionary:
以下是使用字典的一些简单示例
>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'jack': 4098, 'sape': 4139, 'guido': 4127}
>>> tel['jack']
4098
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'jack': 4098, 'guido': 4127, 'irv': 4127}
>>> list(tel)
['jack', 'guido', 'irv']
>>> sorted(tel)
['guido', 'irv', 'jack']
>>> 'guido' in tel
True
>>> 'jack' not in tel
False
The "dict()" constructor builds dictionaries directly from sequences of key-value pairs: "dict()" 构造函数可以直接从键值对序列里创建字典。
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'guido': 4127, 'jack': 4098}
In addition, dict comprehensions can be used to create dictionaries from arbitrary key and value expressions: 此外,字典推导式可以从任意的键值表达式中创建字典
>>> {x: x**2 for x in (2, 4, 6)}
{2: 4, 4: 16, 6: 36}
When the keys are simple strings, it is sometimes easier to specify pairs using keyword arguments: 当关键字是简单字符串时,有时直接通过关键字参数来指定键值对更方便
>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'guido': 4127, 'jack': 4098}
5.6. Looping Techniques
5.6. 循环的技巧
When looping through dictionaries, the key and corresponding value can be retrieved at the same time using the "items()" method.当在字典中循环时,用 "items()" 方法可将关键字和对应的值同时取出
>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.items():
... 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']):To loop over two or more sequences at the same time, the entries can be paired with the "zip()" function.
... print(i, v)
...
0 tic
1 tac
2 toe
当同时在两个或更多序列中循环时,可以用 "zip()" 函数将其内元素一一匹配。
>>> questions = ['name', 'quest', 'favorite color']To loop over a sequence in reverse, first specify the sequence in a forward direction and then call the "reversed()" function.
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
... print('What is your {0}? It is {1}.'.format(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.
当逆向循环一个序列时,先正向定位序列,然后调用 "reversed()" 函数
>>> for i in reversed(range(1, 10, 2)):To loop over a sequence in sorted order, use the "sorted()" function which returns a new sorted list while leaving the source unaltered.
... print(i)
...
9
7
5
3
1
如果要按某个指定顺序循环一个序列,可以用 "sorted()" 函数,它可以在不改动原序列的基础上返回一个新的排好序的序列
>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']It is sometimes tempting to change a list while you are looping over it; however, it is often simpler and safer to create a new list instead.
>>> for f in sorted(set(basket)):
... print(f)
...
apple
banana
orange
pear
有时可能会想在循环时修改列表内容,一般来说改为创建一个新列表是比较简单且安全的
>>> import math
>>> raw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8]
>>> filtered_data = []
>>> for value in raw_data:
... if not math.isnan(value):
... filtered_data.append(value)
...
>>> filtered_data
[56.2, 51.7, 55.3, 52.5, 47.8]
5.7. More on Conditions
5.7. 深入条件控制
The conditions used in "while" and "if" statements can contain any operators, not just 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 using the Boolean operators "and" and "or", and the outcome of a comparison (or of any other Boolean expression) may be negated with "not". These have lower priorities than comparison operators; 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". As always, parentheses can be used to express the desired composition.
比较操作可以通过布尔运算符 "and" 和 "or" 来组合,并且比较操作(或其他任何布尔运算)的结果都可以用 "not" 来取反。这些操作符的优先级低于比较操作符;在它们之中,"not" 优先级最高, "or" 优先级最低,因此 "A andnot 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". When used as a general value and not as a Boolean, the return value of a short-circuit operator 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'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.
>>> non_null = string1 or string2 or string3
>>> non_null
'Trondheim'
注意 Python 与 C 不同,赋值操作不能发生在表达式内部。C程序员可能会对此抱怨,但它避免了一类C程序中常见的错误:想在表达式中写 "==" 时却写成了"="。
5.8. Comparing Sequences and Other Types
5.8. 序列和其它类型的比较
Sequence objects typically 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 Unicode code point number to order individual characters. Some examples of comparisons between sequences of the same type:Sequence objects typically may be compared to other objects with thesame sequence type. The comparison uses lexicographical ordering:first the first two items are compared, and if they differ thisdetermines the outcome of the comparison; if they are equal, the nexttwo 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 allitems of two sequences compare equal, the sequences are consideredequal. If one sequence is an initial sub-sequence of the other, theshorter sequence is the smaller (lesser) one. Lexicographicalordering for strings uses the Unicode code point number to orderindividual characters. Some examples of comparisons between sequencesof the same type:
(1, 2, 3) < (1, 2, 4)Note that comparing objects of different types with "<" or ">" is legal provided that the objects have appropriate comparison methods. For example, mixed numeric types are compared according to their numeric value, so 0 equals 0.0, etc. Otherwise, rather than providing an arbitrary ordering, the interpreter will raise a "TypeError" exception.
[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)
注意对不同类型对象来说,只要待比较对象提供了合适的比较方法,就可以使用"<" 和 ">" 来比较。例如,混合数值类型是通过他们的数值进行比较的,所以0 等于 0.0,等等。否则,解释器将抛出一个 "TypeError" 异常,而不是随便给出一个结果。
-[ Footnotes ]-
-[ 脚注 ]-
[1] Other languages may return the mutated object, which allows method chaining, such as "d->insert("a")->remove("b")->sort();".
[1] 别的语言可能会返回一个可变对象,他们允许方法连续执行,例如"d->insert("a")->remove("b")->sort();"。