首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Python•CHAPTER FOUR

【导言】《Python Tutorial, Release 3.6.4》是适合Python3.6.4语言版本的教程,该教程英文原版来自Python官网,内容权威,版本最新,注重基础,示例代码准确无误,学习高效快捷,非常适合Python编程初学者入门。

该教程英文原版版权属于Python官网 https://www.python.org/ 所有,从英文原版译出的中文版权归译者华哥所有。

该教程发布形式:前部分为中文译文,后部分为对应的英文原文。中文译文中主要示例直接用Python3.6.4解释器演示。

该教程英文原版包括16章和附录共150多页,将分期连续发布,敬请期待!

该教程《第四章 更多的控制流程工具》的译文分成二部分,将分二次连续发布,这是第一部分(1 / 2)。

第四章 更多的控制流程工具

除了while语句刚刚被介绍外,Python还有有别于其它语言的常见控制流程语句,带有一些变化。

4.1 if 语句

也许最有名气的语句类型是if语句,例如:

这里可以是零或更多的elif部分,而else部分是可选的。关键字elif是else if的缩写,有利于避免过度缩排。一个if… elif … elif …序列可以作为其它语言中的switch或case语句的替代。

4.2 for 语句

Python的for语句与你在C或Pascal中所习惯的略有差别。不总是遍历一个由数字组成的等差数列(如在Pascal中一样),或向使用者提供对循环步骤与终止条件进行定义的能力(如C),Python的for语句遍历任意序列中的项(一个列表或一串字符串),按照它们在序列中出现的次序。例如(无双关意):

在进入循环期间(例如复制已选项目),如果你需要修改你正在遍历的序列,建议你首先制作一个副本。遍历序列毫无疑问地不能制作一个副本。切片表示法使这变得尤为方便。

对于for w in words:,这个示例会尝试创建一个无限列表,不断插入defenestrate。

4.3 range() 函数

如果你真的需要遍历一个数字序列,內建的range()函数就派上用场。它生成等差数列:

给出的终点从来不是生成的序列的组成部分;range(10)生成10个数值,一个长度为10的序列的项的合法索引。允许range()起始于另一个数字,或者指定一个不同的增量(甚至负数,有时这被称为“步长(step)”):

要遍历一个序列索引,你可以如下将range()和 len()结合起来:

大多数情况下,然而,使用enumerate()函数是方便的,参看Looping Techniques。如果你恰好打印一个range(),怪事就会发生:

>>>print(range(10))

range(0,10)

从许多方面来说,通过range()行为返回的对象好像是一个列表,但实际上不是。当你遍历它的时候,它是一个返回所需序列连续项的对象,但它事实上没有生成列表,这样节省空间。

我们说这样一个对象是可迭代的,即是适合作为函数和构造的目标,期望从这些函数和构造中获取连续的项,直至资源耗尽为止。我们已经看到for语句是这样的一个迭代器。函数list()是另一种迭代器,它根据可迭代性创建列表:

>>> list(range(5))

[0, 1, 2, 3, 4]

稍后,我们将看到更多的返回迭代器和把迭代器作为参数的函数。

4.4 break 和 continue语句,以及循环中的else子句

break语句,如在C中一样,从最深层封装的for或while循环中跳出来(中断循环)。

循环语句可以有一个else子句,当循环通过耗尽列表(带有for)终止时或者当条件变为false (带有while)时,else子句被执行;但是,当由一个break语句终止循环时,else子句不执行。下列查找质数的循环就是例证:

(是的,这是正确的代码。仔细地看,else子句属于for循环,而非if语句)当跟循环一起使用时,else子句和try语句的else子句,与if语句相比,有更多的共同之处:当没有异常发生时,try语句的else子句执行,而当没有break发生时,循环的else子句执行。关于try语句和异常的更多内容,请参考Handling Exceptions。continue语句也借用于C,继续循环的下一次迭代:

4.5 pass 语句

pass语句什么都不做。当语句在语句构成上需要,但程序不要求做任何事时,可以使用。例如:

>>> while True:

pass # 忙-等待键盘中断(Ctrl+C)

这是通常用于创建最小类。

>>> class MyEmptyClass:

pass

pass语句可以被使用的另一个地方是,当你致力于新代码时,作为函数或条件体的一个占位符,允许你在一个更抽象的水平上不断思考。Pass语句被默默地忽视:

def initlog(*args):

pass # 记住要实现这个!

4.6 定义函数

我们可以创建一个把斐波那契数列写到任意边界的函数。

关键字def引入函数定义。它的后面必须跟着函数名和加上括弧的形式参数列表。组成函数体的语句在下一行开始,并且必须缩进。

函数体的首句可以是任意字符串常量,字符串常量是函数的文档字符串或者docstrings(更多关于docstrings的内容可以在Documentation Strings部分找到)。有些工具使用docstring自动生成联机或打印文档,或让用户交互浏览代码,在你所编写的代码中包含docstrings,是一种好的做法,因此要养成这样的习惯。

函数执行会引入一个用于函数局部变量的新符号表。更精确地,函数中所有变量的赋值都是把值存储在局部符号表中。然而,变量引用首先在局部符号表中查找,然后在封装的函数的局部符号表中,再在全局符号表中,最后在內建名称表中查找。这样,在函数中,全局变量不能被直接赋值(除非在全局语句中命名),尽管它们可以被引用。

函数调用的实际参数(arguments),当函数被调用时,在调用函数的局部符号表中被引入。这样,参数通过值调用的方式被传递(在这里,值总是一个对象引用,而不是对象的值)。当一个函数调用另一个函数时,一个新的局部符号表为那个调用而创建。

函数定义在当前的符号表中引入函数名。函数名的值有一个作为自定义函数被解释器所识别的类型。这个值可以赋值给另一个名称,而这个名称也可以用作函数。这被用作通用的重命名机制。

源于其它语言,你可能会反对fib不是函数,而是一个过程,因为它不返回值。事实上,即使没有返回语句的函数也会返回一个值,尽管这个值相当无趣。这个值被称为None(它是一个內建名)。写入值None通常被解释器禁止,如果它是唯一写入的值。如果你真的想使用print(),可以看到它:

>>> fib(0)

>>> print(fib(0))

None

写一个返回斐波那契数列的数字列表是简单的,而不打印它:

这个示例,跟往常一样,说明了Python的某些新特性:

返回语句返回来自函数的一个值。不带表达式参数的返回,返回None。函数终止失败也会返回None。

result.append(a)语句调用列表对象result的一个方法。方法是“属于”对象并被命名为obj.methodname的函数,在obj处是某个对象(这里也可以是一个表达式),而methodname是被对象类型定义的方法名。不同类型定义不同的方法。不同类型的方法在不引起混乱的情况下可以有一样的名称(允许定义你自己的对象类型和方法,使用classes, 参见Classes)。在这个示例中显示的append()方法,被定义为列表对象,它在列表的末端添加一个新元素,在这个示例中,它是相当于result = result + [a],但更有效。

CHAPTER FOUR MORE CONTROL FLOW TOOLS

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

4.1 if Statements

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

>>> x = int(input("Please enter an integer:"))

Please enter an integer: 42

>>> if x < 0:

x = 0

print('Negative changed to zero')

elif x == 0:

print('Zero')

elif x == 1:

print('Single')

else:

print('More')

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.

4.2 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):

>>> # Measure some strings:

words = ['cat', 'window', 'defenestrate']

>>> for w in words:

print(w, len(w))

cat 3

window 6

defenestrate 12

If you need to modify the sequence you are iterating over while inside the loop (for example to duplicate selected items), it is recommended that you first make a copy. Iterating over a sequence does not implicitly make a copy. The slice notation makes this especially convenient:

>>> for w in words[:]: # Loop over a slice copy of the entire list.

if len(w) > 6:

words.insert(0, w)

['defenestrate', 'cat', 'window', 'defenestrate']

With for w in words:, the example would attempt to create an infinite list, inserting defenestrate over and over again.

4.3 The range() Function

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

>>> for i in range(5):

print(i)

1

2

3

4

The given end point is never part of the generated sequence; range(10) generates 10 values, 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(5, 10)

5 through 9

range(0, 10, 3)

0, 3, 6, 9

range(-10, -100, -30)

-10, -40, -70

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

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

In most such cases, however, it is convenient to use the enumerate() function, see Looping Techniques. A strange thing happens if you just print a range:

>>> print(range(10))

range(0, 10)

In many ways the object returned by range() behaves as if it is a list, but in fact it isn’t. It is an object which returns the successive items of the desired sequence when you iterate over it, but it doesn’t really make the list, thus saving space.

We say such an object is iterable, that is, suitable as a target for functions and constructs that expect something from which they can obtain successive items until the supply is exhausted. We have seen that the for statement is such an iterator. The function list() is another; it creates lists from iterables:

>>> list(range(5))

[0, 1, 2, 3, 4]

Later we will see more functions that return iterables and take iterables as argument.

4.4 break and continue Statements, and else Clauses on Loops

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

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:

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

(Yes, this is the correct code. Look closely: the else clause belongs to the for loop, not the if statement.) When used with a loop, the else clause has more in common with the else clause of a try statement than it does that of if statements: a try statement’s else clause runs when no exception occurs, and a loop’s else clause runs when no break occurs. For more on the try statement and exceptions, see Handling Exceptions. The continue statement, also borrowed from C, continues with the next iteration of the loop:

>>> for num in range(2, 10):

if num % 2 == 0:

print("Found an even number", num)

continue

print("Found a number", num)

Found an even number 2

Found a number 3

Found an even number 4

Found a number 5

Found an even number 6

Found a number 7

Found an even number 8

Found a number 9

4.5 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:

>>> while True:

pass # Busy-wait for keyboard interrupt (Ctrl+C)

This is commonly used for creating minimal classes:

>>> class MyEmptyClass:

pass

Another place pass can be used is as a place-holder for a function or conditional body when you are working on new code, allowing you to keep thinking at a more abstract level. The pass is silently ignored:

>>> def initlog(*args):

pass # Remember to implement this!

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

print(a, end=' ')

a, b = b, a+b

print()

>>> # Now call the function we just defined:

fib(2000)

0 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. (More about docstrings can be found in the section Documentation Strings.) 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 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 local symbol tables of enclosing functions, then in the global symbol table, and finally 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.

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).When a function calls another function, a new local symbol table is created for that call.

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:

>>> f = fib

>>> f(100)

0 1 1 2 3 5 8 13 21 34 55 89

Coming from other languages, you might object that fib is not a function but a procedure since it doesn’t return a value. In fact, even functions without a return statement 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 using print():

>>> fib(0)

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

result.append(a) # see below

a, b = b, a+b

return result

>>> f100 = fib2(100) # call it

>>> f100 # write the result

[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

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

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

• The statement result.append(a) 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, see Classes) 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 + [a], but more efficient.

未完待续

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180210G129X000?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券