Chinaunix首页 | 论坛 | 博客
  • 博客访问: 467211
  • 博文数量: 55
  • 博客积分: 2603
  • 博客等级: 少校
  • 技术积分: 750
  • 用 户 组: 普通用户
  • 注册时间: 2006-12-31 02:30
文章分类

全部博文(55)

文章存档

2011年(1)

2010年(22)

2009年(17)

2008年(15)

我的朋友

分类: Python/Ruby

2010-10-06 00:48:57

.. _tut-structures:

********************************
Data Structures 数据结构
********************************

This chapter describes some things you've learned about already in more detail,
and adds some new things as well.

本章会深入讨论你一些之前已经学过的,而有些是新内容。

.. _tut-morelists:

More on Lists 深入列表
=============================

The list data type has some more methods.  Here are all of the methods of list
objects:

链表类型有很多方法,这里是链表类型的所有方法:

.. method:: list.append(x)
   :noindex:

   Add an item to the end of the list; equivalent to ``a[len(a):] = [x]``.

   把一个元素添加到链表的结尾,相当于 ``a[len(a):] = [x]`` 。

.. method:: list.extend(L)
   :noindex:

   Extend the list by appending all the items in the given list; equivalent to
   ``a[len(a):] = L``.

   将一个给定列表中的所有元素都添加到另一个列表中,相当于 ``a[len(a):] = L`` 。

.. method:: list.insert(i, x)
   :noindex:

   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)`` 。

.. method:: list.remove(x)
   :noindex:

   Remove the first item from the list whose value is *x*. It is an error if there
   is no such item.

   删除链表中值为 *x* 的第一个元素。如果没有这样的元素,就会返回一个错误。

.. method:: list.pop([i])
   :noindex:

   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 库参
   考手册中遇到这样的标记。)

.. method:: list.index(x)
   :noindex:

   Return the index in the list of the first item whose value is *x*. It is an
   error if there is no such item.

   返回链表中第一个值为 *x* 的元素的索引。如果没有匹配的元素就会返回一个错误。

.. method:: list.count(x)
   :noindex:

   Return the number of times *x* appears in the list.
   返回 *x* 在链表中出现的次数。

.. method:: list.sort()
   :noindex:

   Sort the items of the list, in place.

   对链表中的元素就地(原文 in place,意即该操作直接修改调用它的对象——译者)进行排序。

.. method:: list.reverse()
   :noindex:

   Reverse the elements of the list, in place.

   就地倒排链表中的元素。

An example that uses most of the list methods:

下面这个示例演示了链表的大部分方法 ::

   >>> a = [66.25, 333, 333, 1, 1234.5]
   >>> print a.count(333), a.count(66.25), a.count('x')
   2 1 0
   >>> a.insert(2, -1)
   >>> a.append(333)
   >>> a
   [66.25, 333, -1, 333, 1, 1234.5, 333]
   >>> a.index(333)
   1
   >>> a.remove(333)
   >>> a
   [66.25, -1, 333, 1, 1234.5, 333]
   >>> a.reverse()
   >>> a
   [333, 1234.5, 1, 333, -1, 66.25]
   >>> a.sort()
   >>> a
   [-1, 1, 66.25, 333, 333, 1234.5]


.. _tut-lists-as-stacks:

Using Lists as Stacks 把链表当作堆栈使用
----------------------------------------------

.. sectionauthor:: Ka-Ping Yee


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 :meth:`append`.  To retrieve an item from the
top of the stack, use :meth:`pop` without an explicit index.  For example:

链表方法使得链表可以很方便的做为一个堆栈来使用,堆栈作为特定的数据结
构,最先进入的元素最后一个被释放(后进先出)。用 :meth:`append` 方法可以把一
个元素添加到堆栈顶。用不指定索引的 :meth:`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]


.. _tut-lists-as-queues:

Using Lists as Queues 把链表当作队列使用
-------------------------------------------

.. sectionauthor:: Ka-Ping Yee

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 :class:`collections.deque` which was designed to
have fast appends and pops from both ends.  For example:

要实现队列,使用 :class:`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'])


.. _tut-functional:

Functional Programming Tools 函数式编程工具
-------------------------------------------------------

There are three built-in functions that are very useful when used with lists:
:func:`filter`, :func:`map`, and :func:`reduce`.

对于链表来讲,有三个内置函数非常有用: :func:`filter` , :func:`map`,
和 :func:`reduce` 。

``filter(function, sequence)`` returns a sequence consisting of those items from
the sequence for which ``function(item)`` is true. If *sequence* is a
:class:`string` or :class:`tuple`, the result will be of the same type;
otherwise, it is always a :class:`list`. For example, to compute some primes:

``filter(function, sequence)`` 返回一个sequence(序列),包括了给定序
列中所有调用 ``function(item)`` 后返回值为true的元素。(如果可能的话,
会返回相同的类型)。如果该 *序列(sequence)* 是一个 :class:`string`
(字符串)或者 :class:`tuple` (元组),返回值必定是同一类型,否则,它
总是 :class:`list` 。例如,以下程序可以计算部分素数 ::

   >>> def f(x): return x % 2 != 0 and x % 3 != 0
   ...
   >>> filter(f, range(2, 25))
   [5, 7, 11, 13, 17, 19, 23]

``map(function, sequence)`` calls ``function(item)`` for each of the sequence's
items and returns a list of the return values.  For example, to compute some
cubes:

``map(function, sequence)`` 为每一个元素依次调用 ``function(item)`` 并将返回值
组成一个链表返回。例如,以下程序计算立方 ::

   >>> def cube(x): return x*x*x
   ...
   >>> map(cube, range(1, 11))
   [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]

More than one sequence may be passed; the function must then have as many
arguments as there are sequences and is called with the corresponding item from
each sequence (or ``None`` if some sequence is shorter than another).  For
example:

可以传入多个序列,函数也必须要有对应数量的参数,执行时会依次用各序列上
对应的元素来调用函数(如果某些序列比其它的短,就用 ``None`` 来代替)。如果把
None做为一个函数传入,则直接返回参数做为替代。例如 ::

   >>> seq = range(8)
   >>> def add(x, y): return x+y
   ...
   >>> map(add, seq, seq)
   [0, 2, 4, 6, 8, 10, 12, 14]

``reduce(function, sequence)`` returns a single value constructed by calling the
binary function *function* on the first two items of the sequence, then on the
result and the next item, and so on.  For example, to compute the sum of the
numbers 1 through 10:

``reduce(func, sequence)`` 返回一个单值,它是这样构造的:首先以序列的
前两个元素调用函数 *function* ,再以返回值和第三个参数调用,依次执行下去。例如,以
下程序计算 1 到 10 的整数之和 ::

   >>> def add(x,y): return x+y
   ...
   >>> reduce(add, range(1, 11))
   55

If there's only one item in the sequence, its value is returned; if the sequence
is empty, an exception is raised.

如果序列中只有一个元素,就返回它,如果序列是空的,就抛出一个异常。

A third argument can be passed to indicate the starting value.  In this case the
starting value is returned for an empty sequence, and the function is first
applied to the starting value and the first sequence item, then to the result
and the next item, and so on.  For example, :

可以传入第三个参数做为初始值。如果序列是空的,就返回初始值,否则函数会
先接收初始值和序列的第一个元素,然后是返回值和下一个元素,依此类推。例
如 ::

   >>> def sum(seq):
   ...     def add(x,y): return x+y
   ...     return reduce(add, seq, 0)
   ...
   >>> sum(range(1, 11))
   55
   >>> sum([])
   0

Don't use this example's definition of :func:`sum`: since summing numbers is
such a common need, a built-in function ``sum(sequence)`` is already provided,
and works exactly like this.

不要像示例中这样定义 :func:`sum` :因为合计数值是一个通用的需求,早已
有内置的 ``sum(sequence)`` 函数,非常好用。

.. versionadded:: 2.3


List Comprehensions 列表推导式
-----------------------------------------

List comprehensions provide a concise way to create lists without resorting to
use of :func:`map`, :func:`filter` and/or :keyword:`lambda`. The resulting list
definition tends often to be clearer than lists built using those constructs.
Each list comprehension consists of an expression followed by a :keyword:`for`
clause, then zero or more :keyword:`for` or :keyword:`if` clauses.  The result
will be a list resulting from evaluating the expression in the context of the
:keyword:`for` and :keyword:`if` clauses which follow it.  If the expression
would evaluate to a tuple, it must be parenthesized. :

列表推导式提供了一个创建链表的简单途径,无需使用 :func:`map` , :func:`filter` 以及
:keyword:`lambda` 。以定义方式得到列表通常要比使用构造函数创建这些列表更清晰。每一个列表推导式包括
在一个 :keyword:`for` 语句之后的表达式,零或多个 :keyword:`for` 或
:keyword:`if` 语句。返回值是由 :keyword:`for` 或
:keyword:`if` 子句之后的表达式得到的元素组成的列表。如果想要得到一个元组,必须要加
上括号。 ::

   >>> freshfruit = ['  banana', '  loganberry ', 'passion fruit  ']
   >>> [weapon.strip() for weapon in freshfruit]
   ['banana', 'loganberry', 'passion fruit']
   >>> vec = [2, 4, 6]
   >>> [3*x for x in vec]
   [6, 12, 18]
   >>> [3*x for x in vec if x > 3]
   [12, 18]
   >>> [3*x for x in vec if x < 2]
   []
   >>> [[x,x**2] for x in vec]
   [[2, 4], [4, 16], [6, 36]]
   >>> [x, x**2 for x in vec]  # error - parens required for tuples
     File "", line 1, in ?
       [x, x**2 for x in vec]
                  ^
   SyntaxError: invalid syntax
   >>> [(x, x**2) for x in vec]
   [(2, 4), (4, 16), (6, 36)]
   >>> vec1 = [2, 4, 6]
   >>> vec2 = [4, 3, -9]
   >>> [x*y for x in vec1 for y in vec2]
   [8, 6, -18, 16, 12, -36, 24, 18, -54]
   >>> [x+y for x in vec1 for y in vec2]
   [6, 5, -7, 8, 7, -5, 10, 9, -3]
   >>> [vec1[i]*vec2[i] for i in range(len(vec1))]
   [8, 12, -54]

List comprehensions are much more flexible than :func:`map` and can be applied
to complex expressions and nested functions:

列表推导式比 :func:`map` 更复杂,可使用复杂的表达式和嵌套函数 ::

   >>> [str(round(355/113.0, i)) for i in range(1,6)]
   ['3.1', '3.14', '3.142', '3.1416', '3.14159']


Nested List Comprehensions 嵌套的列表推导式
---------------------------------------------------

If you've got the stomach for it, list comprehensions can be nested. They are a
powerful tool but -- like all powerful tools -- they need to be used carefully,
if at all.

如果你不会晕菜的话,列表推导式可以嵌套。它们可以是非常强力的工具——就像
所有的强力工具一样——它们用起来也需要格外小心。

Consider the following example of a 3x3 matrix held as a list containing three
lists, one list per row:

考虑以下的 3x3 矩阵的例子,一个列表中包含了三个列表,每个一行 ::

    >>> mat = [
    ...        [1, 2, 3],
    ...        [4, 5, 6],
    ...        [7, 8, 9],
    ...       ]

Now, if you wanted to swap rows and columns, you could use a list
comprehension:

现在,如果你想交换行和列,可以用列表推导式 ::

    >>> print [[row[i] for row in mat] for i in [0, 1, 2]]
    [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

Special care has to be taken for the *nested* list comprehension:

*嵌套* 列表推导式的时候要特别小心:

    To avoid apprehension when nesting list comprehensions, read from right to
    left.

    为了不被嵌套的列表推导式搞晕,从右往左读。

A more verbose version of this snippet shows the flow explicitly:

接下来有一个更容易读的版本 ::

    for i in [0, 1, 2]:
        for row in mat:
            print row[i],
        print

In real world, you should prefer built-in functions to complex flow statements.
The :func:`zip` function would do a great job for this use case:

实用中,你可以利用内置函数完成复杂的流程语句。函数 :func:`zip` 在这个
例子中可以搞定大量的工作 ::

    >>> zip(*mat)
    [(1, 4, 7), (2, 5, 8), (3, 6, 9)]

See :ref:`tut-unpacking-arguments` for details on the asterisk in this line.

关于这行代码中带有星号的参数,请参见 :ref:`tut-unpacking-arguments` 。

.. _tut-del:

The :keyword:`del` statement 删除语句
=====================================

There is a way to remove an item from a list given its index instead of its
value: the :keyword:`del` statement.  This differs from the :meth:`pop` method
which returns a value.  The :keyword:`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:

有个方法可以从列表中按给定的索引而不是值来删除一个子项:
:keyword:`del` 语句。它不同于有返回值的 :meth:`pop` 方法。语句
:keyword:`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
   []

:keyword:`del` can also be used to delete entire variables:

:keyword:`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 :keyword:`del` later.

此后再引用命名 ``a`` 会引发错误(直到另一个值赋给它为止)。我们在后面
的内容中可以看到 :keyword:`del` 的其它用法。

.. _tut-tuples:

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
:ref:`typesseq`).  Since Python is an evolving language, other sequence data
types may be added.  There is also another standard sequence data type: the
*tuple*.

我们知道链表和字符串有很多通用的属性,例如索引和切割操作。它们是 *序
列* 类型(参见 :ref:`typesseq` )中的两种。因为 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))

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).

如你所见,元组在输出时总是有括号的,以便于正确表达嵌套结构。在输入时可
以有或没有括号,不过经常括号都是必须的(如果元组是一个更大的表达
式的一部分)。

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!'`` 是 *元组封装* (tuple packing)的
一个例子:值 ``12345`` , ``54321`` 和 ``'hello!'`` 被封装进元组。其逆
操作可能是这样 ::

   >>> x, y, z = t

This is called, appropriately enough, *sequence unpacking* and works for any
sequence on the right-hand side.  Sequence unpacking requires the list of
variables on the left to 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 )其实只是元组封装和序列拆封的一个结合。

.. XXX Add a bit on the difference between tuples and lists.


.. _tut-sets:

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(集合)* 。集合是一个无序不重复元素的
集。基本功能包括关系测试和消除重复元素。集合对象还支持 union(联
合),intersection(交),difference(差)和sysmmetric difference(对
称差集)等数学运算。

Here is a brief demonstration:

以下是一个简单的演示 ::

   >>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
   >>> fruit = set(basket)               # create a set without duplicates
   >>> fruit
   set(['orange', 'pear', 'apple', 'banana'])
   >>> 'orange' in fruit                 # fast membership testing
   True
   >>> 'crabgrass' in fruit
   False

   >>> # Demonstrate set operations on unique letters from two words
   ...
   >>> a = set('abracadabra')
   >>> b = set('alacazam')
   >>> a                                  # unique letters in a
   set(['a', 'r', 'b', 'c', 'd'])
   >>> a - b                              # letters in a but not in b
   set(['r', 'd', 'b'])
   >>> a | b                              # letters in either a or b
   set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
   >>> a & b                              # letters in both a and b
   set(['a', 'c'])
   >>> a ^ b                              # letters in a or b but not both
   set(['r', 'd', 'b', 'm', 'z', 'l'])


.. _tut-dictionaries:

Dictionaries 字典
==========================

Another useful data type built into Python is the *dictionary* (see
:ref:`typesmapping`). 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 :meth:`append` and
:meth:`extend`.

另一个非常有用的 Python 内建数据类型是 *字典* (参见
:ref:`typesmapping` )。字典在某些语言中可能称为 ``联合内存``
( ``associative memories`` )或 ``联合数组`` ( 
``associative arrays`` )。序列是以连续的整数为索引,与此不同的是,字
典以 *关键字* 为索引,关键字可以是任意不可变类型,通常用字符串或数值。如果元组中只包含字
符串和数字,它可以做为关键字,如果它直接或间接的包含了可变对象,就不能
当做关键字。不能用链表做关键字,因为链表可以用索引、切割或者 :meth:`append`
和 :meth:`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`` 来删除键:
值对(key:value)。如果你用一个已经存在的关键字存储值,以前为该关键字
分配的值就会被遗忘。试图从一个不存在的键中取值会导致错误。

The :meth:`keys` method of a dictionary object returns a list of all the keys
used in the dictionary, in arbitrary order (if you want it sorted, just apply
the :meth:`sort` method to the list of keys).  To check whether a single key is
in the dictionary, use the :keyword:`in` keyword.

字典的 :meth:`keys` 方法返回由所有关键字组成的链表,该链表的顺序不定(如果你
需要它有序,只能调用关键字链表的 :meth:`sort` 方法)。可以用 
:keyword:`in` 关键字检查字典中是否存在某一关键字。

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']
   >>> 'guido' in tel
   True

The :func:`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. :

链表中存储关键字-值对元组的话,:func:`dict` 可以从中直接构造字典。键-值
对来自某个特定模式时,可以用链表推导式简单的生成关键字-值链表。 ::

   >>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
   {'sape': 4139, 'jack': 4098, 'guido': 4127}
   >>> dict([(x, x**2) for x in (2, 4, 6)])     # use a list comprehension
   {2: 4, 4: 16, 6: 36}

Later in the tutorial, we will learn about Generator Expressions which are even
better suited for the task of supplying key-values pairs to the :func:`dict`
constructor.

在入门指南后面的内容中,我们将会学习更适于为 :func:`dict` 构造器生成键值对的生成器表达式。

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, 'jack': 4098, 'guido': 4127}


.. _tut-loopidioms:

Looping Techniques 循环技巧
======================================

When looping through dictionaries, the key and corresponding value can be
retrieved at the same time using the :meth:`iteritems` method. :

在字典中循环时,关键字和对应的值可以使用 :meth:`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 :func:`enumerate` function. :

在序列中循环时,索引位置和对应值可以使用 :func:`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 :func:`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 :func:`reversed` function. :

需要逆向循环序列的话,先正向定位序列,然后调用 :func:`reversed` 函数 ::

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

To loop over a sequence in sorted order, use the :func:`sorted` function which
returns a new sorted list while leaving the source unaltered. ::

要按排序后的顺序循环序列的话,使用 :func:`sorted` 函数,它不改动原序列,而是
生成一个新的已排序的序列。 ::

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


.. _tut-conditions:

More on Conditions 深入条件控制
=======================================

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 and not B or C`` 等于 
``(A and (notB)) 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'
   >>> 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 程序中司空见惯的错误:想要在解析式中使 ``==`` 时误用了
``=`` 操作符。

.. _tut-comparing:

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 of the same type:

序列对象可以与相同类型的其它对象比较。比较操作按 *字典序* 进行:首先比较
前两个元素,如果不同,就决定了比较的结果;如果相同,就比较后两个元素,
依此类推,直到所有序列都完成比较。如果两个元素本身就是同样类型的序列,
就递归字典序比较。如果两个序列的所有子项都相等,就认为序列相等。如果一
个序列是另一个序列的初始子序列,较短的一个序列就小于另一个。字符串的字
典序按照单字符的 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.

需要注意的是不同类型的对象比较是合法的。输出结果是确定而非任意的:类型
按它们的名字排序。因而,一个链表(list)总是小于一个字符串(string),
一个字符串(string)总是小于一个元组(tuple)等等。 [#]_ 数值类型比较时会统
一它们的数据类型,所以0等于0.0,等等。

.. rubric:: Footnotes

.. [#] The rules for comparing objects of different types should not be relied upon;
   they may change in a future version of the language.

.. [#] Python 并不承诺不同类型之间进行比较时的明确规则,当前的方式在未来的
   版本中可能会改变

阅读(1224) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~