python3.6中文文档-《Python3.6官方文档》– 4.更多流程控制语句

4 更多流程控制语句

除了刚才介绍的while语句,Python也引入了其它语言常见的流程控制语法,并稍作变化。

4.1 if语句

或许最广为人知的控制语句就是if语句。例如:

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

if语句可以有零个或者更多elif分支,else分支是非强制要求有的。关键词"elif’是比"else if’短的,这可以有效避免过度缩进问题。而且,if … elif … elif …语句可以替换其它语言中的switch/case语句。

4.2. for Statements

Python中的for语句与你可能用过的C或者Pascal语言中的for语句有点不同。与通常通过一个等差数列进行迭代(像Pascal语言),或者给予用户自主迭代和终止步骤(就像C语言),Python的For语句以集合(list或者string)中的元素为迭代单元,按照它们在集合中的顺序逐个迭代。例如(我并没有含沙射影):

>>> # Measure some strings:

... words = ["cat", "window", "defenestrate"]

>>> for w in words:

... print(w, len(w))

...

cat 3

window 6

defenestrate 12

如果你需要在迭代中时修改集合(例如为集合复制某个元素),我们建议你先为集合创建副本。直接迭代集合并不能为集合创建副本,切片操作可以很方便的做到这一点。

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

... if len(w) > 6:

... words.insert(0, w)

...

>>> words

["defenestrate", "cat", "window", "defenestrate"]

靠着使用for w in words:语法,我们可以用不断插入defenestrate单词,来尝试创建出很大的集合。

4.3. range()函数

如果你需要迭代一组连续数字,内建函数range()正好可以帮上忙。它生成递增数列:

>>> for i in range(5):

... print(i)

...

0

1

2

3

4

指定的尾数入参永远不是生成序列的一部分; range(10)生成十个数字,代表着会生成十个长度的序列。我们甚至可以让序列从另一个数字开始,或者指定另一个递增值(尽管被否认,但它有时被称为"步长’):

range(5, 10)

5, 6, 7, 8, 9

range(0, 10, 3)

0, 3, 6, 9

range(-10, -100, -30)

-10, -40, -70

为了迭代集合的索引,我们可以把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

如果你打印一个range函数,会发生奇怪的事情:

>>> print(range(10))

range(0, 10)

从很多特性上看,rang()函数返回的对象都表现的像是一个list,但实际上它不是。当你迭代它时,它返回了你想要的连续数字,但是它为了节省内存空间,不是个真正的list。

我们称这种对象为可迭代的,即适合成为可以期待得到有限连续项的函数或者结构的目标。我们已经知道,for语句是一个类似的迭代器,list()函数也是一个类似的迭代器;它以可迭代对象创建list。

>>> list(range(5))

[0, 1, 2, 3, 4]

稍后我们可以看到更多函数可以返回可迭代对象,或者把可迭代对象作为入参。

4.4.循环中的break、continue语句和else子句

break语句,就像在C语言中一样,跳出最内层的for或者while循环。

循环语句也许有一个else子句;它在for语句的list循环终结时或者while语句的条件变为false时执行,但在循环被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

(是的,这是一段没有错误的代码。仔细看:else子句是属于for循环,而不是if语句)

当与循环一起使用时,它的else子句与在try语句块和if语句块的else子句功能类似:当try语句块没有异常时,else分支触发执行;当循环没有被break终止时,else分支触发执行。想要学习更多try语句块和异常,参见Handling Exceptions

continue语句,是从C语言借鉴的,直接执行循环的下一次。

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

pass语句什么也不执行。它可以背用于语法需要,但程序并不想执行任何任务。例如:

>>> while True:

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

...

它通常被用于创建一个最小的类:

>>> class MyEmptyClass:

... pass

...

另一个用处是,当你正在写新的代码,可以将pass写在函数体或者条件子句体中,用以标记占位,这使你在更抽象层面思考。pass会被自动忽略。

>>> def initlog(*args):

... pass # Remember to implement this!

...

4.6 函数定义

我们可以写一个可以输出不超过指定边界值的斐波那契数列的函数:

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

关键词def定义了一个函数。它后边是函数名字和被括号包括起来的一串参数。函数体的声明是从下一行开始的,而且必须缩进。

函数体的第一行可以是一个随意的字符串数组;字符串数组是函数的文档字符串或者docstring。(更多关于docstring的说明可以在文档API部分找到)。有一些工具可以使用docstrings制作在线文档或者打印文档,或者让用户交互式的浏览代码;在代码中写入docstrings是一个很好的做法,你应该养成习惯。

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

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

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

>>>

>>> fib

>>> f = fib

>>> f(100)

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

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

>>>

>>> fib(0)

>>> print(fib(0))

None

我们来写一个简单的示例,用于演示如何从函数中返回一个包含菲波那契数列的数值链表,而不是打印它: 、

>>>

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

和以往一样,上面的例子演示了一些新的 Python 功能:

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值