5.Data Structures 数据结构

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 更多关于列表

The list data type has some more methods. Here are all of the methods of list objects:
列表这个数据类型有一些方法.这里是操作列表的方法:

list.append(x)

Add an item to the end of the list. Equivalent to a[len(a):] = [x].
把一个项目加到列表的末尾.等价于 a[len(a):] = [x].

list.extend(iterable)

Extend the list by appending all the items from the iterable. Equivalent to a[len(a):] = iterable.
把迭代器指向的所有元素插入到列表中,等价于a[len(a):] = iterable

list.insert(i,x)

Insert an item at a given position. The first argument is the 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).
在给定的位置插入一个元素.第一个参数是插入元素的前面的下标.所以, a.insert(0,x) 就是在列表的前面插入元素, a.insert(len(a),x) 等价于 a.append(x)

list.remove(x)

Remove the first item from the list whose value is equal to x. It raises a ValueError if there is no such item.
删除列表中值等于'x'的第一个元素. 如果没有这个元素,就会抛出'ValueError'错误

list.pop([i])

Remove the item at the given position in the list, and return it. 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() 删除并返回列表中的最后一个元素.(方法前面中'i'的中括号表示这个参数是可选的,而不是要求你在这个位置输入中括号.你将会在Python库文件参考中频繁看到这个用法.)

list.clear()

Remove all items from the list. Equivalent to del a[:].
删除列表中的所有元素.

list.index(x[,start[,end]])

Return zero-based index in the list of the first item whose value is equal to x. Raises a ValueError if there is no such item.
从0开始,返回列表中值等于'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'开始算的.
例如:

>>> a = [1,2,3,4,5]
>>> a
[1, 2, 3, 4, 5]
>>> a.index(3)
2
>>> a[2:4]
[3, 4]  # a 从2到4的切片是[3,4]
>>> a.index(3,2,4)
2       #这里是在a列表的子序列[3,4]中查找'3'的下标,是2,不是0
list.count(x)

Return the number of times x appears in the list.
返回列表中'x'出现的次数

list.sort(key=None,reverse=False)

Sort the items of the list in place (the arguments can be used for sort customization, see sorted() for their explanation).
将列表中的元素排序.参数可以用来定制化排序,可以查看'sort()'中相关的说明

list.reverse()

反转列表

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']
>>> fruits.count('apple')
2
>>> fruits.count('tangerine')
0
>>> fruits.index('banana')
3
>>> fruits.index('banana', 4)  # Find next banana starting a position 4 从下标4开始查找下一个'banana'
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'

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.
你也许已经注意到向insert,remove或者sort仅仅是修改列表,并没有返回值输出--他们返回缺省的None.这是Python关于可变的数据结构的设计原理.

5.1.1. Using Lists as Stacks 将列表作为栈使用

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 将列表作为队列使用

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 列表生成式

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 = []
>>> for x in range(10):
...     squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> x
9
>>>

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:
请注意这里创建(或者重写了)一个名称为'x'的变量,在循环结束后'x'依然存在.我们可以没有其他任何副作用地得到平方的列表,使用:

>>> squares = list(map(lambda x: x**2, range(10)))
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>>

or, equivalently:
或者,等价于:

>>> squares = [x**2 for x in range(10)]
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>>

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 forand if clauses which follow it. For example, this listcomp combines the elements of two lists if they are not equal:
列表生成式由括号,以及包含for语句后面跟着的一个表达式组成. 结果是一个新的列表,通过执行for和if语句中的表达式生成.例如,这个列表生成式生成了两个不相等的列表元素的组合:

>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

and it’s equivalent to:
并且它等价于:

>>> combs = []
>>> 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)]

Note how the order of the for and if statements is the same in both these snippets.
注意到这些片段中的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]
>>> # 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 "<stdin>", line 1, in <module>
    [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]

List comprehensions can contain complex expressions and nested functions:
列表生成去可以保护复杂的表达式和嵌套的函数:

>>> 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 嵌套列表生成式

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:
考虑下面的例子中,3*4矩阵是由3个长度为4的列表组成的列表:

>>>> matrix = [
...     [1, 2, 3, 4],
...     [5, 6, 7, 8],
...     [9, 10, 11, 12],
... ]

The following list comprehension will transpose rows and columns:
下面的列表生成式将会调换行跟列:

>>> [[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

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:
正如我们在前面章节看到的,嵌套的列表生成式是可以用for语句是实现的,所有这个例子等价于:

>>> transposed = []
>>> 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]]

which, in turn, is the same as:
反过来,也是一样的:

>>> transposed = []
>>> 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]]

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:
实际上,你应该更喜欢内置的函数来复杂化流控制语句。对于这样的使用案例,zip()函数将会起到很大的作用:

>>> list(zip(*matrix))
[(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]

See Unpacking Argument Lists for details on the asterisk in this line.
更多详细内容请查看 Unpacking Argument Lists 参数列表拆包 for details on the asterisk in this line.

5.2. The del statement 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 a[0]
>>> a
[1, 66.25, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.25, 1234.5]
>>> del a[:]
>>> a
[]

del can also be used to delete entire variables:
del 也可以用来删除整个变量:

>>> del a

Referencing 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 元组和序列

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: thetuple.
我们可以看到列表和字符创有很多公共的属性,例如下标和切片操作。它们是序列数据结构的两个例子。因为Python是一个进化的语言,其他序列数据类型可以添加。这里也有另外一个标准的序列数据类型:元组。

A tuple consists of a number of values separated by commas, for instance:
一个元组包含多个值,由逗号隔开,例如:

>>> 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))
>>> # Tuples are immutable:  元组是不可变的
... t[0] = 88888
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
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])

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.
正如你所见,输出的元组总是被括号括起来,所有嵌套的元组能够正确解析。虽然大部分情况下括号是必要的(如果元组是一个复杂表达式的一部分),但在输入元组时,括号可以有,也可以没有。不能为元组中的独立元素赋值,但是可以创建包含可变对象的元组,例如列表。

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.
虽然元组看起来很像列表,但是他们经常是被用在不用的场景和不同的目的。元组是不可变的,经常包含一个异质元素的序列,通过拆包或者下标来访问。列表是可变的,它的元素经常是同质的,通过列表上面的迭代器来访问。

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 = ()
>>> 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! 语句是元组包装的一个例子。三个值:1234554321hello! 在一个元组中被包装在一起。相反的操作也是可能的:

>>> x, y, z = t

This 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 集合

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也包含集合的数据类型。set是是没有重复元素的无序集合。基本的用法包括是否成员测试和消除重复项。集合对象也支持数学操作,像并集,交集,差集和对称差异。

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 字典

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中另一个很有用的内置数据类型就是字典。在其他编程语言中,字典经常作为关联内存或者关联数组。不像序列使用数字来索引的,字典使用键值来索引的,键值可以是任何不可变的类型。字符串和数组总是可以作为键值。如果元组中只包含字符串,数字或元组,也是可以作为键值的。如果元组包含任何可变对象,不管是直接或间接的,都不能作为键值。不能把列表作为键值,因为列表可以通过下标赋值、切片赋值或像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 inkeyword.
在字典中使用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:
dicr()构造器直接从键值对序列中创建字典:

>>>> 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:
另外,字典生成式也可以用来从任意的key和value的表达式中创建字典:

>>> {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 循环技巧

When looping through dictionaries, the key and corresponding value can be retrieved at the same time using the items() method.
当循环遍历字典时,使用items() 方法可以同时检索key及其关联的值。

>>> 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']):
...     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 {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.

To loop over a sequence in reverse, first specify the sequence in a forward direction and then call the reversed()function.
反向遍历序列时,首先指定一个顺序的序列,然后调用reversed() 函数。

>>> for i in reversed(range(1, 10, 2)):
...     print(i)
...
9
7
5
3
1

To loop over a sequence in sorted order, use the sorted() function which returns a new sorted list while leaving the source unaltered.
按顺序遍历序列,使用sorted()函数可以返回一个新的有序列表,且原序列保持不变。

>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
...     print(f)
...
apple
banana
orange
pear

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.
有时想要在遍历列表时修改列表的值。然而,有时创建一个新的列表却是简单又安全。

>>> 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 更多关于条件控制

The conditions used in while and if statements can contain any operators, not just comparisons.
whileif语句中使用条件控制可以包含任何的操作,不仅仅是比较。

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.
比较操作符innot in 检查一个值是否在(或不在)一个序列中。比较操作符 isis 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.
比较操作符可以用布尔操作符 andor 组合在一起,并且比较符(或任何其他的布尔表达式)可以用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. When used as a general value and not as a Boolean, the return value of a short-circuit operator is the last evaluated argument.
布尔操作符 andor 被称为 短路操作符:从左到右来计算他们的值,并且当结果被确定后,计算过程就会停止。例如: 如果AC是真,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.8. 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 Unicode code point number to order individual characters. Some examples of comparisons between sequences of the same type:
序列对象可以跟同一序列类型的其他对象比较。比较时按照字典顺序:首先比较这两个对象的第一个元素,他们是否不同决定了比较的结果。如果他们是一样的,比较接下来的两个元素等等,直到其中一个序列结束。如果比较的两个对象是同一类型,字典序比较将会导致递归。如果两个序列的所有元素都相等,就认为这两个序列相等。如果一个序列是另外一个序列的初始子序列,较短的序列是小的一个。字符串的字典顺序使用Unicode编码的序号来排序单个字符。下面是一些同一类型的序列的比较:

(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 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 TypeErrorexception.
请注意,如果对象具有适当的比较方法,则将不同类型的对象与<>进行比较是合法的。例如,混合数字类型通过他们的算数值类比较,例如 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();. |

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269