中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > C/C++
Python Tutorial(2)
作者:未知 时间:2005-09-13 23:28 出处:Blog.ChinaUnix.net 责编:chinaitpower
              摘要:Python Tutorial(2)
从第四章开始

4. 深入流程控制 More Control Flow Tools

Besides the while statement just introduced, Python knows the usual control flow statements known from other languages, with some twists.

除了前面介绍的 while 语句,Python 还从别的语言中借鉴了一些流程控制功能,并有所改变。


4.1 if 语句 if Statements

Perhaps the most well-known statement type is the if statement. For example:

也许最有名的是 if 语句。例如:

>>> x = int(raw_input("Please enter an integer: "))
>>> if x < 0:
... x = 0
... print 'Negative changed to zero'
... elif x == 0:
... print 'Zero'
... elif x == 1:
... print 'Single'
... else:
... print 'More'
...

There can be zero or more elif parts, and the else part is optional. The keyword `elif' is short for `else if', and is useful to avoid excessive indentation. An if ... elif ... elif ... sequence is a substitute for the switch or case statements found in other languages.

可能会有零到多个 elif 部分,else 是可选的。关键字“elif” 是“ else if ”的缩写,这个可以有效避免过深的缩进。if ... elif ... elif ... 序列用于替代其它语言中的 switch 或 case 语句。


4.2 for 语句 for Statements

The for statement in Python differs a bit from what you may be used to in C or Pascal. Rather than always iterating over an arithmetic progression of numbers (like in Pascal), or giving the user the ability to define both the iteration step and halting condition (as C), Python's for statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence. For example (no pun intended):

Python 中的 for 语句和 C 或 Pascal 中的略有不同。通常的循环可能会依据一个等差数值步进过程(如Pascal)或由用户来定义迭代步骤和中止条件(如 C ),Python 的 for 语句依据任意序列(链表或字符串)中的子项,按它们在序列中的顺序来进行迭代。例如(没有暗指):

>>> # Measure some strings:
... a = ['cat', 'window', 'defenestrate']
>>> for x in a:
... print x, len(x)
...
cat 3
window 6
defenestrate 12

It is not safe to modify the sequence being iterated over in the loop (this can only happen for mutable sequence types, such as lists). If you need to modify the list you are iterating over (for example, to duplicate selected items) you must iterate over a copy. The slice notation makes this particularly convenient:

在迭代过程中修改迭代序列不安全(只有在使用链表这样的可变序列时才会有这样的情况)。如果你想要修改你迭代的序列(例如,复制选择项),你可以迭代它的复本。通常使用切片标识就可以很方便的做到这一点:

>>> for x in a[:]: # make a slice copy of the entire list
... if len(x) > 6: a.insert(0, x)
...
>>> a
['defenestrate', 'cat', 'window', 'defenestrate']


4.3 range() 函数 The range() Function

If you do need to iterate over a sequence of numbers, the built-in function range() comes in handy. It generates lists containing arithmetic progressions:

如果你需要一个数值序列,内置函数range()可能会很有用,它生成一个等差级数链表。

>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

The given end point is never part of the generated list; range(10) generates a list of 10 values, exactly the legal indices for items of a sequence of length 10. It is possible to let the range start at another number, or to specify a different increment (even negative; sometimes this is called the `step'):

range(10) 生成了一个包含10个值的链表,它准确的用链表的索引值填充了这个长度为10的列表,所生成的链表中不包括范围中的结束值。也可以让range操作从另一个数值开始,或者可以指定一个不同的步进值(甚至是负数,有时这也被称为“步长”):

>>> range(5, 10)
[5, 6, 7, 8, 9]
>>> range(0, 10, 3)
[0, 3, 6, 9]
>>> range(-10, -100, -30)
[-10, -40, -70]

To iterate over the indices of a sequence, combine range() and len() as follows:

需要迭代链表索引的话,如下所示结合使 用range()len()

>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
... print i, a[i]
...
0 Mary
1 had
2 a
3 little
4 lamb


4.4 breakcontinue 语句, 以及 循环中的 else 子句 break and continue Statements, and else Clauses on Loops

The break statement, like in C, breaks out of the smallest enclosing for or while loop.

break 语句和 C 中的类似,用于跳出最近的一级 forwhile 循环。

The continue statement, also borrowed from C, continues with the next iteration of the loop.

continue 语句是从 C 中借鉴来的,它表示循环继续执行下一次迭代。

Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the list (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement. This is exemplified by the following loop, which searches for prime numbers:

循环可以有一个 else 子句;它在循环迭代完整个列表(对于 for )或执行条件为 false (对于 while )时执行,但循环被 break 中止的情况下不会执行。以下搜索素数的示例程序演示了这个子句:

>>> for n in range(2, 10):
... for x in range(2, n):
... if n % x == 0:
... print n, 'equals', x, '*', n/x
... break
... else:
... # loop fell through without finding a factor
... print n, 'is a prime number'
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3


4.5 pass 语句 pass Statements

The pass statement does nothing. It can be used when a statement is required syntactically but the program requires no action. For example:

pass 语句什么也不做。它用于那些语法上必须要有什么语句,但程序什么也不做的场合,例如:

>>> while True:
... pass # Busy-wait for keyboard interrupt
...


4.6 Defining Functions

We can create a function that writes the Fibonacci series to an arbitrary boundary:

>>> def fib(n):    # write Fibonacci series up to n
... """Print a Fibonacci series up to n."""
... a, b = 0, 1
... while b < n:
... print b,
... a, b = b, a+b
...
>>> # Now call the function we just defined:
... fib(2000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

The keyword def introduces a function definition. It must be followed by the function name and the parenthesized list of formal parameters. The statements that form the body of the function start at the next line, and must be indented. The first statement of the function body can optionally be a string literal; this string literal is the function's documentation string, or docstring.

关键字 def 引入了一个函数定义。在其后必须跟有函数名和包括形式参数的圆括号。函数体语句从下一行开始,必须是缩进的。函数体的第一行可以是一个字符串值,这个字符串是该函数的 (文档字符串(documentation string)),也可称作 docstring

There are tools which use docstrings to automatically produce online or printed documentation, or to let the user interactively browse through code; it's good practice to include docstrings in code that you write, so try to make a habit of it.

有些文档字符串工具可以在线处理或打印文档,或让用户交互的浏览代码;在代码中加入文档字符串是一个好的作法,应该养成这个习惯。

The execution of a function introduces a new symbol table used for the local variables of the function. More precisely, all variable assignments in a function store the value in the local symbol table; whereas variable references first look in the local symbol table, then in the global symbol table, and then in the table of built-in names. Thus, global variables cannot be directly assigned a value within a function (unless named in a global statement), although they may be referenced.

执行函数时会为局部变量引入一个新的符号表。所有的局部变量都存储在这个局部符号表中。引用参数时,会先从局部符号表中查找,然后是全局符号表,然后是内置命名表。因此,全局参数虽然可以被引用,但它们不能在函数中直接赋值(除非它们用 global 语句命名)。

The actual parameters (arguments) to a function call are introduced in the local symbol table of the called function when it is called; thus, arguments are passed using call by value (where the value is always an object reference, not the value of the object).4.1 When a function calls another function, a new local symbol table is created for that call.

函数引用的实际参数在函数调用时引入局部符号表,因此,实参总是传值调用(这里的值总是一个对象引用,而不是该对象的值)。4.2 一个函数被另一个函数调用时,一个新的局部符号表在调用过程中被创建。

A function definition introduces the function name in the current symbol table. The value of the function name has a type that is recognized by the interpreter as a user-defined function. This value can be assigned to another name which can then also be used as a function. This serves as a general renaming mechanism:

函数定义在当前符号表中引入函数名。作为用户定义函数,函数名有一个为解释器认可的类型值。这个值可以赋给其它命名,使其能够作为一个函数来使用。这就像一个重命名机制:

>>> fib
<function fib at 10042ed0>
>>> f = fib
>>> f(100)
1 1 2 3 5 8 13 21 34 55 89

You might object that fib is not a function but a procedure. In Python, like in C, procedures are just functions that don't return a value. In fact, technically speaking, procedures do return a value, albeit a rather boring one. This value is called None (it's a built-in name). Writing the value None is normally suppressed by the interpreter if it would be the only value written. You can see it if you really want to:

你可能认为fib不是一个函数( function ),而是一个过程( procedure )。Python 和 C 一样,过程只是一个没有返回值的函数。实际上,从技术上讲,过程也有一个返回值,虽然是一个不讨人喜欢的。这个值被称为 None (这是一个内置命名)。如果一个值只是 None 的话,通常解释器不会写一个 None 出来,如果你真想要查看它的话,可以这样做:

>>> print fib(0)
None

It is simple to write a function that returns a list of the numbers of the Fibonacci series, instead of printing it:

以下示例演示了如何从函数中返回一个包含菲波那契数列的数值链表,而不是打印它:

>>> def fib2(n): # return Fibonacci series up to n
... """Return a list containing the Fibonacci series up to n."""
... result = []
... a, b = 0, 1
... while b < n:
... result.append(b) # see below
... a, b = b, a+b
... return result
...
>>> f100 = fib2(100) # call it
>>> f100 # write the result
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

This example, as usual, demonstrates some new Python features:

和以前一样,这个例子演示了一些新的 Python 功能:

  • The return statement returns with a value from a function. return without an expression argument returns None. Falling off the end of a procedure also returns None.

    return 语句从函数中返回一个值,不带表达式的 return 返回 None。过程结束后也会返回 None

  • The statement result.append(b) calls a method of the list object result. A method is a function that `belongs' to an object and is named obj.methodname, where obj is some object (this may be an expression), and methodname is the name of a method that is defined by the object's type. Different types define different methods. Methods of different types may have the same name without causing ambiguity. (It is possible to define your own object types and methods, using classes, as discussed later in this tutorial.) The method append() shown in the example, is defined for list objects; it adds a new element at the end of the list. In this example it is equivalent to "result = result + [b]", but more efficient.

    语句 result.append(b) 称为链表对象 result 的一个方法( method )。方法是一个“属于”某个对象的函数,它被命名为 obj.methodename ,这里的 obj 是某个对象(可能是一个表达式),methodename 是某个在该对象类型定义中的方法的命名。不同的类型定义不同的方法。不同类型可能有同样名字的方法,但不会混淆。(当你定义自己的对象类型和方法时,可能会出现这种情况,本指南后面的章节会介绍如何使用类型)。示例中演示的 append()方法由链表对象定义,它向链表中加入一个新元素。在示例中它等同于""result = result + [b]"",不过效率更高。


4.7 深入函数定义 More on Defining Functions

It is also possible to define functions with a variable number of arguments. There are three forms, which can be combined.

有时需要定义参数个数可变的函数。有三个方法可以达到目的,我们可以组合使用它们。


4.7.1 参数默认值 Default Argument Values

The most useful form is to specify a default value for one or more arguments. This creates a function that can be called with fewer arguments than it is defined to allow. For example:

最有用的形式是给一个或多个参数指定默认值。这样创建的函数可以用较少的参数来调用。例如:

def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
while True:
ok = raw_input(prompt)
if ok in ('y', 'ye', 'yes'): return True
if ok in ('n', 'no', 'nop', 'nope'): return False
retries = retries - 1
if retries < 0: raise IOError, 'refusenik user'
print complaint

This function can be called either like this: ask_ok('Do you really want to quit?') or like this: ask_ok('OK to overwrite the file?', 2).

这个函数还可以用以下的方式调用:ask_ok('Do you really want to quit?'),或者像这样:ask_ok('OK to overwrite the file?', 2)

This example also introduces the in keyword. This tests whether or not a sequence contains a certain value.

这个示例还介绍了关键字 in 。它检测一个序列中是否包含某个给定的值。

The default values are evaluated at the point of function definition in the defining scope, so that

默认值在函数定义段被解析,如下所示:

i = 5

def f(arg=i):
print arg

i = 6
f()

will print 5.

以上代码会打印5。

Important warning: The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes. For example, the following function accumulates the arguments passed to it on subsequent calls:

重要警告:默认值只会解析一次。当默认值是一个可变对象,诸如链表、字典或大部分类实例时,会产生一些差异。例如,以下函数在后继的调用中会累积它的参数值:

def f(a, L=[]):
L.append(a)
return L

print f(1)
print f(2)
print f(3)

This will print

这会打印出:

[1]
[1, 2]
[1, 2, 3]

If you don't want the default to be shared between subsequent calls, you can write the function like this instead:

如果你不想在不同的函数调用之间共享参数默认值,可以如下面的实例一样编写函数:

def f(a, L=None):
if L is None:
L = []
L.append(a)
return L


4.7.2 关键字参数 Keyword Arguments

Functions can also be called using keyword arguments of the form "keyword = value". For instance, the following function:

函数可以通过关键字参数的形式来调用,形如"keyword = value"。例如,以下的函数:

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
print "-- This parrot wouldn't", action,
print "if you put", voltage, "Volts through it."
print "-- Lovely plumage, the", type
print "-- It's", state, "!"

could be called in any of the following ways:

可以用以下的任一方法调用:

parrot(1000)
parrot(action = 'VOOOOOM', voltage = 1000000)
parrot('a thousand', state = 'pushing up the daisies')
parrot('a million', 'bereft of life', 'jump')

but the following calls would all be invalid:

不过以下几种调用是无效的:

parrot()                     # required argument missing
parrot(voltage=5.0, 'dead') # non-keyword argument following keyword
parrot(110, voltage=220) # duplicate value for argument
parrot(actor='John Cleese') # unknown keyword

In general, an argument list must have any positional arguments followed by any keyword arguments, where the keywords must be chosen from the formal parameter names. It's not important whether a formal parameter has a default value or not. No argument may receive a value more than once -- formal parameter names corresponding to positional arguments cannot be used as keywords in the same calls. Here's an example that fails due to this restriction:

通常,参数列表中的每一个关键字都必须来自于形式参数,每个参数都有对应的关键字。形式参数有没有默认值并不重要。实际参数不能一次赋多个值——形式参数不能在同一次调用中同时使用位置和关键字绑定值。这里有一个例子演示了在这种约束下所出现的失败情况:

>>> def function(a):
... pass
...
>>> function(0, a=0)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: function() got multiple values for keyword argument 'a'

When a final formal parameter of the form **name is present, it receives a dictionary containing all keyword arguments whose keyword doesn't correspond to a formal parameter. This may be combined with a formal parameter of the form *name (described in the next subsection) which receives a tuple containing the positional arguments beyond the formal parameter list. (*name must occur before **name.) For example, if we define a function like this:

引入一个形如 **name 的参数时,它接收一个 字典 ,该字典包含了所有未出现在形式参数列表中的关键字参数。这里可能还会组合使用一个形如 *name 的形式参数,它接收一个元组(下一节中会详细介绍),包含了所有没有出现在形式参数列表中的参数值。(*name 必须在 **name 之前出现) 例如,我们这样定义一个函数:

def cheeseshop(kind, *arguments, **keywords):
print "-- Do you have any", kind, '?'
print "-- I'm sorry, we're all out of", kind
for arg in arguments: print arg
print '-'*40
keys = keywords.keys()
keys.sort()
for kw in keys: print kw, ':', keywords[kw]

It could be called like this:

它可以像这样调用:

cheeseshop('Limburger', "It's very runny, sir.",
"It's really very, VERY runny, sir.",
client='John Cleese',
shopkeeper='Michael Palin',
sketch='Cheese Shop Sketch')

and of course it would print:

当然它会按如下内容打印:

-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
client : John Cleese
shopkeeper : Michael Palin
sketch : Cheese Shop Sketch

Note that the sort() method of the list of keyword argument names is called before printing the contents of the keywords dictionary; if this is not done, the order in which the arguments are printed is undefined.

注意sort()方法在关键字字典内容打印前被调用,否则的话,打印参数时的顺序是未定义的。


4.7.3 可变参数表 Arbitrary Argument Lists

Finally, the least frequently used option is to specify that a function can be called with an arbitrary number of arguments. These arguments will be wrapped up in a tuple. Before the variable number of arguments, zero or more normal arguments may occur.

最后,一个最不常用的选择是可以让函数调用可变个数的参数。这些参数被包装进一个元组。在这些可变个数的参数之前,可以有零到多个普通的参数:

def fprintf(file, format, *args):
file.write(format % args)


4.7.4 参数列表的分拆 Unpacking Argument Lists

The reverse situation occurs when the arguments are already in a list or tuple but need to be unpacked for a function call requiring separate positional arguments. For instance, the built-in range() function expects separate start and stop arguments. If they are not available separately, write the function call with the *-operator to unpack the arguments out of a list or tuple:

另有一种相反的情况: 当你要传递的参数已经是一个列表但要调用的函数却接受分开一个个的参数值. 这时候你要把已有的列表拆开来. 例如内建函数 range() 需要要独立的 start, stop 参数. 你可以在调用函数时加一个 * 操作符来自动把参数列表拆开:

>>> range(3, 6)             # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> range(*args) # call with arguments unpacked from a list
[3, 4, 5]


4.7.5 Lambda 形式 Lambda Forms

By popular demand, a few features commonly found in functional programming languages and Lisp have been added to Python. With the lambda keyword, small anonymous functions can be created. Here's a function that returns the sum of its two arguments: "lambda a, b: a+b". Lambda forms can be used wherever function objects are required. They are syntactically restricted to a single expression. Semantically, they are just syntactic sugar for a normal function definition. Like nested function definitions, lambda forms can reference variables from the containing scope:

出于实际需要,有几种通常在功能性语言和 Lisp 中出现的功能加入到了 Python 。通过 lambda 关键字,可以创建短小的匿名函数。这里有一个函数返回它的两个参数的和:"lambda a, b: a+b"。 Lambda 形式可以用于任何需要的函数对象。出于语法限制,它们只能有一个单独的表达式。语义上讲,它们只是普通函数定义中的一个语法技巧。类似于嵌套函数定义,lambda 形式可以从包含范围内引用变量:

>>> def make_incrementor(n):
... return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43


4.7.6 文档字符串 Documentation Strings

There are emerging conventions about the content and formatting of documentation strings.

这里介绍的概念和格式。

The first line should always be a short, concise summary of the object's purpose. For brevity, it should not explicitly state the object's name or type, since these are available by other means (except if the name happens to be a verb describing a function's operation). This line should begin with a capital letter and end with a period.

第一行应该是关于对象用途的简介。简短起见,不用明确的陈述对象名或类型,因为它们可以从别的途径了解到(除非这个名字碰巧就是描述这个函数操作的动词)。这一行应该以大写字母开头,以句号结尾。

If there are more lines in the documentation string, the second line should be blank, visually separating the summary from the rest of the description. The following lines should be one or more paragraphs describing the object's calling conventions, its side effects, etc.

如果文档字符串有多行,第二行应该空出来,与接下来的详细描述明确分隔。接下来的文档应该有一或多段描述对象的调用约定、边界效应等。

The Python parser does not strip indentation from multi-line string literals in Python, so tools that process documentation have to strip indentation if desired. This is done using the following convention. The first non-blank line after the first line of the string determines the amount of indentation for the entire documentation string. (We can't use the first line since it is generally adjacent to the string's opening quotes so its indentation is not apparent in the string literal.) Whitespace ``equivalent'' to this indentation is then stripped from the start of all lines of the string. Lines that are indented less should not occur, but if they occur all their leading whitespace should be stripped. Equivalence of whitespace should be tested after expansion of tabs (to 8 spaces, normally).

Python的解释器不会从多行的文档字符串中去除缩进,所以必要的时候应当自己清除缩进。这符合通常的习惯。第一行之后的 第一个非空行决定了整个文档的缩进格式。(我们不用第一行是因为它通常紧靠着起始的引号,缩进格式显示的不清楚。)留白“相当于”是字符串的起始缩进。每 一行都不应该有缩进,如果有缩进的话,所有的留白都应该清除掉。留白的长度应当等于扩展制表符的宽度(通常是8个空格)。

Here is an example of a multi-line docstring:

以下是一个多行文档字符串的示例:

>>> def my_function():
... """Do nothing, but document it.
...
... No, really, it doesn't do anything.
... """
... pass
...
>>> print my_function.__doc__
Do nothing, but document it.

No, really, it doesn't do anything.



Footnotes

... object).4.1
Actually, call by object reference would be a better description, since if a mutable object is passed, the caller will see any changes the callee makes to it (items inserted into a list).
...函数引用的实际参数在函数调用时引入局部符号表,因此,实参总是传值调用(这里的值总是一个对象引用,而不是该对象的值)。4.2
事实上,称之为调用对象的引用更合适。因为一个可变对象传递进来后,调用者可以看到被调用对象的任何修改(如在链表中插入一个新的子项)。

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:

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

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

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

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

通过添加指定链表的所有元素来扩充链表,相当于 a[len(a):] = L

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)

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

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

pop( [i])
Remove the item at the given position in the list, and return it. If no index is specified, a.pop() returns the last item in the list. The item is also removed from 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 库参考手册中遇到这样的标记。)

index( x)
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的元素的索引。如果没有匹配的元素就会返回一个错误。

count( x)
Return the number of times x appears in the list.

返回x在链表中出现的次数。

sort( )
Sort the items of the list, in place.

对链表中的元素进行适当的排序。

reverse( )
Reverse the elements of the list, in place.

倒排链表中的元素。

An example that uses most of the list methods:

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

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


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

You can also use a list conveniently as a queue, where the first element added is the first element retrieved (``first-in, first-out''). To add an item to the back of the queue, use append(). To retrieve an item from the front of the queue, use pop() with 0 as the index. For example:

你也可以把链表当做队列使用,队列作为特定的数据结构,最先进入的元素最先释放(先进先出)。使用 append()方法可以把元素添加到队列最后,以0为参数调用 pop() 方法可以把最先进入的元素释放出来。例如:

>>> queue = ["Eric", "John", "Michael"]
>>> queue.append("Terry") # Terry arrives
>>> queue.append("Graham") # Graham arrives
>>> queue.pop(0)
'Eric'
>>> queue.pop(0)
'John'
>>> queue
['Michael', 'Terry', 'Graham']


5.1.3 函数化编程工具 Functional Programming Tools

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

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

"filter(function, sequence)" returns a sequence (of the same type, if possible) consisting of those items from the sequence for which function(item) is true. For example, to compute some primes:

"filter(function, sequence)"返回一个序列(sequence),包括了给定序列中所有调用function(item)后返回值为true的元素。(如果可能的话,会返回相同的类型)。例如,以下程序可以计算部分素数:

>>> 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(func, sequence)" returns a single value constructed by calling the binary function func 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)" 返回一个单值,它是这样构造的:首先以序列的前两个元素调用函数,再以返回值和第三个参数调用,依次执行下去。例如,以下程序计算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 sum(): since summing numbers is such a common need, a built-in function sum(sequence) is already provided, and works exactly like this. New in version 2.3.

不要像示例中这样定义sum():因为合计数值是一个通用的需求,在2.3版中,提供了内置的sum(sequence) 函数。 New in version 2.3.

5.1.4 链表推导式 List Comprehensions

List comprehensions provide a concise way to create lists without resorting to use of map(), filter() and/or 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 for clause, then zero or more for or if clauses. The result will be a list resulting from evaluating the expression in the context of the for and if clauses which follow it. If the expression would evaluate to a tuple, it must be parenthesized.

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

>>> 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 "<stdin>", 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 map() and can be applied to functions with more than one argument and to nested functions:

链表推导式比 map()更复杂,可调用多个参数和嵌套函数。

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


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 can also be used to remove slices from a list (which we did earlier by assignment of an empty list to the slice). For example:

有一个方法可从链表中删除指定索引的元素:del 语句。这个方法也可以从链表中删除切片(之前我们是把一个空链表赋给切片)。例如:

>>> a = [-1, 1, 66.6, 333, 333, 1234.5]
>>> del a[0]
>>> a
[1, 66.6, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.6, 1234.5]

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.

此后再引用这个名字会发生错误(至少要到给它赋另一个值为止)。后面我们还会发现del的其它用法。


5.3 元组(Tuples)和序列(Sequences )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. Since Python is an evolving language, other sequence data types may be added. There is also another standard sequence data type: the tuple.

我们知道链表和字符串有很多通用的属性,例如索引和切片操作。它们是序列类型中的两种。因为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 alway enclosed in parentheses, so that nested tuples are interpreted correctly; they may be input with or without surrounding parentheses, although often parentheses are necessary anyway (if the tuple is part of a larger expression).

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

Tuples have many uses. For example: (x, y) coordinate pairs, employee records from a database, etc. Tuples, like strings, are immutable: it is not possible to assign to the individual items of a tuple (you can simulate much of the same effect with slicing and concatenation, though). It is also possible to create tuples which contain mutable objects, such as lists.

元组有很多用途。例如(x, y)坐标点,数据库中的员工记录等等。元组就像字符串,不可改变:不能给元组的一个独立的元素赋值(尽管你可以通过联接和切片来模仿)。也可以通过包含可变对象来创建元组,例如链表。

A special problem is the construction of tuples containing 0 or 1 items: the syntax has some extra quirks to accommodate these. Empty tuples are constructed by an empty pair of parentheses; a tuple with one item is constructed by following a value with a comma (it is not sufficient to enclose a single value in parentheses). Ugly, but effective. For example:

一个特殊的问题是构造包含零个或一个元素的元组:为了适应这种情况,语法上有一些额外的改变。一对空的括号可以创建空元组;要创建一个单元素元组可以在值后面跟一个逗号(在括号中放入一个单值是不够的)。丑陋,但是有效。例如:

>>> empty = ()
>>> singleton = 'hello', # <-- note trailing comma
>>> len(empty)
0
>>> len(singleton)
1
>>> singleton
('hello',)

The statement t = 12345, 54321, 'hello!' is an example of tuple packing: the values 12345, 54321 and 'hello!' are packed together in a tuple. The reverse operation is also possible:

语句 t = 12345, 54321, 'hello!' 是元组封装(sequence packing)的一个例子:值 12345, 54321 和 'hello!' 被封装进元组。其逆操作可能是这样:

>>> x, y, z = t

This is called, appropriately enough, sequence unpacking. Sequence unpacking requires that the list of variables on the left have the same number of elements as the length of the sequence. Note that multiple assignment is really just a combination of tuple packing and sequence unpacking!

这个调用被称为序列拆封非常合适。序列拆封要求左侧的变量数目与序列的元素个数相同。要注意的是可变参数(multiple assignment )其实只是元组封装和序列拆封的一个结合!

There is a small bit of asymmetry here: packing multiple values always creates a tuple, and unpacking works for any sequence.

这里有一点不对称:封装多重参数通常会创建一个元组,而拆封操作可以作用于任何序列。


5.4 Dictionaries 字典

Another useful data type built into Python is the dictionary. Dictionaries are sometimes found in other languages as ``associative memories'' or ``associative arrays''. Unlike sequences, which are indexed by a range of numbers, dictionaries are indexed by keys, which can be any immutable type; strings and numbers can always be keys. Tuples can be used as keys if they contain only strings, numbers, or tuples; if a tuple contains any mutable object either directly or indirectly, it cannot be used as a key. You can't use lists as keys, since lists can be modified in place using their append() and extend() methods, as well as slice and indexed assignments.

另一个非常有用的Python内建数据类型是字典。字典在某些语言中可能称为“联合内存”(``associative memories'')或“联合数组”(``associative arrays'')。序列是以连续的整数为索引,与此不同的是,字典以关键字为索引,关键字可以是任意不可变类型,通常用字符串或数值。如果元组中只包含字符串和数字,它可以做为关键字,如果它直接或间接的包含了可变对象,就不能当做关键字。不能用链表做关键字,因为链表可以用它们的append()extend()方法,或者用切片、或者通过检索变量来即时改变。

It is best to think of a dictionary as an unordered set of key: value pairs, with the requirement that the keys are unique (within one dictionary). A pair of braces creates an empty dictionary: {}. Placing a comma-separated list of key:value pairs within the braces adds initial key:value pairs to the dictionary; this is also the way dictionaries are written on output.

理解字典的最佳方式是把它看做无序的关键字:值 对(key:value pairs)集合,关键字必须是互不相同的(在同一个字典之内)。一对大括号创建一个空的字典:{}。初始化链表时,在大括号内放置一组逗号分隔的关键字:值对,这也是字典输出的方式。

The main operations on a dictionary are storing a value with some key and extracting the value given the key. It is also possible to delete a key:value pair with del. If you store using a key that is already in use, the old value associated with that key is forgotten. It is an error to extract a value using a non-existent key.

字典的主要操作是依据关键字来存储和析取值。也可以用 del来删除关键字:值对。如果你用一个已经存在的关键字存储值,以前为该关键字分配的值就会被遗忘。试图析取从一个不存在的关键字中读取值会导致错误。

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

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

Here is a small example using a dictionary:

这是一个关于字典应用的小示例:

>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'sape': 4139, 'guido': 4127, 'jack': 4098}
>>> tel['jack']
4098
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'guido': 4127, 'irv': 4127, 'jack': 4098}
>>> tel.keys()
['guido', 'irv', 'jack']
>>> tel.has_key('guido')
True

The dict() constructor builds dictionaries directly from lists of key-value pairs stored as tuples. When the pairs form a pattern, list comprehensions can compactly specify the key-value list.

链表中存储关键字-值对元组的话,字典可以从中直接构造。关键字-值对来自一个模式时,可以用链表推导式简单的表达关键字-值链表。

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


5.5 循环技巧 Looping Techniques

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

在字典中循环时,关键字和对应的值可以使用 iteritems()方法同时解读出来。

>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.iteritems():
... print k, v
...
gallahad the pure
robin the brave

When looping through a sequence, the position index and corresponding value can be retrieved at the same time using the enumerate() function.

在序列中循环时,索引位置和对应值可以使用enumerate()函数同时得到。

>>> for i, v in enumerate(['tic', 'tac', 'toe']):
... print i, v
...
0 tic
1 tac
2 toe

To loop over two or more sequences at the same time, the entries can be paired with the zip() function.

同时循环两个或更多的序列,可以使用 zip() 整体解读。

>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
... print 'What is your %s? It is %s.' % (q, a)
...
What is your name? It is lancelot.
What is your quest? It is the holy grail.
What is your favorite color? It is blue.


5.6 深入条件控制 More on Conditions

The conditions used in while and if statements above can contain other operators besides comparisons.

用于 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 比较操作符审核值是否在一个区间之内。操作符 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 小于 bb 等于c

Comparisons may be combined by the Boolean operators and and or, and the outcome of a comparison (or of any other Boolean expression) may be negated with not. These all have lower priorities than comparison operators again; between them, not has the highest priority, and or the lowest, so that A and not B or C is equivalent to (A and (not B)) or C. Of course, parentheses can be used to express the desired composition.

比较操作可以通过逻辑操作符 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. In general, the return value of a short-circuit operator, when used as a general value and not as a Boolean, is the last evaluated argument.

逻辑操作符 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.7 比较序列和其它类型 Comparing Sequences and Other Types

Sequence objects may be compared to other objects with the same sequence type. The comparison uses lexicographical ordering: first the first two items are compared, and if they differ this determines

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有