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. 从列表中删除值等于x的第一项。It raises a ValueError if there is no such item.如果没有此类项,则会引发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. 如果未指定索引,a.pop()将删除并返回列表中的最后一项。(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. (方法签名中i周围的方括号表示参数是可选的,而不是您应该在该位置键入方括号。)。You will see this notation frequently in the Python Library Reference.)您将在Python库参考中经常看到这种符号。)

list.clear()

Remove all items from the list. 从列表中删除所有项目。Equivalent to del a[:].相当于del a[:]

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

Return zero-based index in the list of the first item whose value is equal to x. 返回值等于x的第一项列表中从零开始的索引。Raises a ValueError if there is no such item.如果没有此类项,则引发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. 可选参数startend在切片表示法中被解释为,用于将搜索限制在列表的特定子序列中。The returned index is computed relative to the beginning of the full sequence rather than the start argument.返回的索引是相对于完整序列的开头而不是start参数计算的。

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).对列表中的项目进行适当排序(参数可用于排序自定义,请参阅sorted()以了解其解释)。

list.reverse()

Reverse the elements of the list in place.将列表中的元素原地反转。

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
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. 您可能已经注意到,像insertremovesort这样只修改列表的方法没有打印返回值——它们返回默认值None1 This is a design principle for all mutable data structures in Python.这是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. 例如,[None, 'hello', 10]不排序,因为整数不能与字符串比较,而None不能与其他类型比较。Also, there are some types that don’t have a defined ordering relation. 此外,还有一些类型没有定义的排序关系。For example, 3+4j < 5+7j isn’t a valid comparison.例如,3+4j < 5+7j不是有效的比较。

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(). 要将项添加到堆栈顶部,请使用append()To retrieve an item from the top of the stack, use pop() without an explicit index. 要从堆栈顶部检索项,请使用不带显式索引的pop()For example:例如:

>>> 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. 要实现一个队列,请使用collections.deque,它被设计为两端都有快速的附加和弹出。For example:例如:

>>> 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]

Note that this creates (or overwrites) a variable named x that still exists after the loop completes. 请注意,这将创建(或覆盖)一个名为x的变量,该变量在循环完成后仍然存在。We can calculate the list of squares without any side effects using:我们可以使用以下方法计算正方形列表,而不会产生任何副作用:

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. 列表推导式由方括号组成,方括号中包含一个表达式,后跟for子句,然后是零个或多个forif子句。The result will be a new list resulting from evaluating the expression in the context of the for and if clauses which follow it. 结果将是一个新的列表,它是在后面的forif子句的上下文中对表达式求值的结果。For example, this listcomp combines the elements of two lists if they are not equal:例如,如果两个列表的元素不相等,则此listcomp将它们组合在一起:

>>> [(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.请注意,forif语句在这两个代码段中的顺序是如何相同的。

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:考虑以下3x4矩阵示例,该矩阵由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:正如我们在上一节中所看到的,嵌套的listcomp是在其后面的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.有关此行中星号的详细信息,请参阅解包参数列表

5.2. The del statementdel语句

There is a way to remove an item from a list given its index instead of its value: the del statement. 有一种方法可以从给定索引而非值的列表中删除项:del语句。This differs from the pop() method which returns a value. 这与返回值的pop()方法不同。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). del语句还可以用于从列表中删除切片或清除整个列表(我们之前通过向切片分配一个空列表实现了这一点)。For example:例如:

>>> 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 a

Referencing the name a hereafter is an error (at least until another value is assigned to it). 此后引用名称a是一个错误(至少在为其指定另一个值之前)。We’ll find other uses for del later.我们稍后会找到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. 由于Python是一种不断发展的语言,因此可能会添加其他序列数据类型。There is also another standard sequence data type: the tuple.还有另一种标准的序列数据类型:元组

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). 元组是不可变的,通常包含一个异构的元素序列,这些元素可以通过解包(请参阅本节后面的内容)或索引(在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. 一个特殊的问题是包含0或1项的元组的构造:语法有一些额外的怪癖来适应这些。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. 语句t = 12345, 54321, 'hello!'元组打包的一个示例:值1234554321'hello!'被打包成一个元组。The reverse operation is also possible:也可以进行反向操作:

>>> 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. Python还包括的数据类型。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.集合对象还支持并、交、差和对称差等数学运算。

Curly braces or the set() function can be used to create sets. 花括号或set()函数可用于创建集合。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(),而不是{};后者创建了一个空字典,我们将在下一节讨论这个数据结构。

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). Python中另一个有用的数据类型是字典(请参见映射类型:字典)。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().不能将列表用作键,因为可以使用索引分配、切片分配或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. 还可以使用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.使用不存在的键提取值是错误的。

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). 在字典上执行list(d)会以插入顺序返回字典中使用的所有键的列表(如果希望对其进行排序,只需使用sorted(d)To check whether a single key is in the dictionary, use the in keyword.要检查字典中是否有单个键,请使用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循环技术

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']):
... 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 i in sorted(basket):
... print(i)
...
apple
apple
banana
orange
orange
pear

Using set() on a sequence eliminates duplicate elements. 对序列使用set()可以消除重复的元素。The use of sorted() in combination with set() over a sequence is an idiomatic way to loop over unique elements of the sequence in sorted order.在序列上结合使用sorted()set()是按排序顺序循环序列中唯一元素的惯用方法。

>>> 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 are membership tests that determine whether a value is in (or not in) a container. innot in的比较运算符是成员资格测试,用于确定值是否在容器中。The operators is and is not compare whether two objects are really the same object. 运算符isis not用于比较两个对象是否真的是同一个对象。All comparison operators have the same priority, which is lower than that of all numerical operators.所有比较运算符的优先级相同,低于所有数值运算符的优先级。

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. 可以使用布尔运算符andor组合比较,比较(或任何其他布尔表达式)的结果可以用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. 它们的优先级低于比较运算符;在它们之间,not具有最高优先级而or具有最低优先级,因此A and not B or C相当于(A and (not B)) or CAs always, parentheses can be used to express the desired composition.和往常一样,括号可以用来表示所需的构图。

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. 布尔运算符andor是所谓的短路运算符:它们的参数从左到右求值,结果确定后立即停止求值。For example, if A and C are true but B is false, A and B and C does not evaluate the expression C. 例如,如果ACtrue,但Bfalse,则A and B and C不会计算表达式CWhen used as a general value and not as a Boolean, the return value of a short-circuit operator is the last evaluated argument.当用作常规值而不是布尔值时,短路运算符的返回值是最后计算的参数。

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 inside expressions must be done explicitly with the walrus operator :=. 注意,在Python中,与C不同,表达式内部的赋值必须使用walrus运算符:=显式完成。This avoids a common class of problems encountered in C programs: typing = in an expression when == was intended.这避免了C程序中遇到的一类常见问题:在使用==时在表达式中键入=

5.8. Comparing Sequences and Other Types比较序列和其他类型

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. 字符串的字典排序使用Unicode代码点编号对单个字符进行排序。Some examples of comparisons between sequences of the same type:相同类型序列之间比较的一些示例:

(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 TypeError exception.例如,混合的数字类型会根据它们的数值进行比较,因此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();.其他语言可能会返回经过修改的对象,这允许方法连缀,例如d->insert("a")->remove("b")->sort();