python控制流-2017-7-18

本文介绍了Python中的控制流语句,包括if、for、while等,并详细讲解了break、continue及else子句的用法。同时,文章还探讨了如何定义函数,包括默认参数值、关键字参数和任意参数列表等高级特性。

4. 控制流

除了前面介绍的while语句,Python也有其它语言常见的流程控制语句,但是稍有不同

4.1 if 语句



最为人所知的语句类型可能是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'

结果:Please enter an integer: -1
Negative changed to zero

可以有零个或多个elif部分,else部分是可选的。关键字'elif'是'else if'的简写,可以有效避免过深的缩进。if...elif...elif...序列用于替代其它语言中的switchcase语句。

4.2 for语句

Python中的for语句和你可能熟悉的C或Pascal中的有点不同。和常见的等差数列迭代(如Pascal中)或让用户能够自定义迭代步骤和停止条件(如 C)不一样,Python 的 for 语句按照元素出现的顺序迭代任何序列(列表或字符串)。例如:

words = ['cat', 'window', 'defenestrate']
for w in words:
    print w, len(w)

结果:

cat 3
window 6
defenestrate 12
如果要在循环内修改正在迭代的序列(例如,复制所选的项目),建议首先制作副本。迭代序列不会隐式地创建副本。使用切片就可以很容易地做到:

words = ['cat', 'window', 'defenestrate']
for w in words[:]:  # Loop over a slice copy of the entire list.
    if len(w) > 6:
        words.insert(0, w)
print words

结果:

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


4.3 range()函数

如果你确实需要遍历一个数字序列,内置函数 range()非常方便。 它将生成包含等差数列的列表:
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

给定的终点永远不会在生成的列表中;range(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]
若要依据索引迭代序列,你可以结合使用 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 break和continue语句,以及循环中的else子句

break语句和C中的类似,用于跳出最近的forwhile循环。
循环语句可以有一个else子句;当(for)循环迭代完整个列表或(while)循环条件变为假,而非由break语句终止时,就会执行这个else语句。下面循环搜索质数的代码例示了这一点:

for n in range(2, 10):
     for x in range(2, n):     #range(2,2)为【】空
         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语句。)

与在if语句中的用法相比,循环中的else子句与try语句的else子句有更多的共同点:try语句的else子句在未出现异常时运行,循环的else子句在未出现break时运行。更多关于try语句和异常的内容,请参见处理异常


continue语句,也是从C语言借来的,表示继续下一次迭代:
for num in range(2, 10): #2-----9
     if num % 2 == 0:
         print "Found an even number", num
         continue
     print "Found a number", num

result:
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,
         a, b = b, a+b
 # Now call the function we just defined:
fib(2000)

result:

0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

关键字def引入函数的定义其后必须跟有函数名和以括号标明的形式参数列表。组成函数体的语句从下一行开始,且必须缩进。

函数体的第一行可以是一个可选的字符串文本;此字符串是该函数的文档字符串,或称为docstring(更多关于 docstrings 的内容可以在文档字符串一节中找到。)有工具使用 docstrings 自动生成在线的或可打印的文档,或者让用户在代码中交互浏览;在您编写的代码中包含 docstrings 是很好的做法,所以让它成为习惯吧。

执行一个函数会引入一个用于函数的局部变量的新符号表。更确切地说,函数中的所有的赋值都是将值存储在局部符号表;而变量引用首先查找局部符号表,然后是上层函数的局部符号表,然后是全局符号表,最后是内置名字表。然而,在函数内部无法给一个全局变量直接赋值(除非在一个global语句中命名),虽然可以引用它们。

函数调用的实际参数在函数被调用时引入被调函数的局部符号表;因此,参数的传递使用传值调用(这里的始终是对象的引用,不是对象的值)。[1]一个函数调用另一个函数时,会为该调用创建一个新的局部符号表。

如果你使用过其他语言,你可能会反对说:fib不是一个函数,而是一个过程(子程序),因为它并不返回任何值。事实上,没有return语句的函数也返回一个值,尽管是一个很无聊的值。此值被称为None(它是一个内置的名称)。如果None只是唯一的输出,解释器通常不会打印出来。如果你真的想看到这个值,可以使用print 语句:

>>> 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
print f100             # write the result

此示例中,像往常一样,演示了一些新的 Python 功能:

  • return语句从函数中返回一个值。不带表达式参数的return返回None函数直接结束后也返回None
  • 语句result.append(a)调用了列表对象result 的一个方法方法是‘隶属于'某个对象的函数,被命名成obj.methodname的形式,其中obj是某个对象(或是一个表达式),methodname是由对象类型定义的方法的名称。不同类型定义了不同的方法。不同类型的方法可能具有相同的名称,而不会引起歧义。(也可以使用class 定义你自己的对象类型和方法,请参见本例中所示的append()方法是列表对象定义的。它在列表的末尾添加一个新的元素。在本例中它等同于result= result +[a],但效率更高。

4.7.更多关于定义函数

可以定义具有可变数目的参数的函数。有三种形式,也可以结合使用。

4.7.1.默认参数值

最有用的形式是指定一个或多个参数的默认值。这种方法创建的函数被调用时,可以带有比定义的要少的参数。例如:

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

这个函数可以通过几种方式调用:

  • 只给出强制参数: ask_ok (' Do you really want to quit?')
  • 给出一个可选的参数: ask_ok ('OKto overwrite the file?', 2)
  • 或者给出所有的参数: ask_ok ('OK to overwritethe file?', 2,'Come on, only yes or no!')

此示例还引入了in关键字。它测试一个序列是否包含特定的值。

重要的警告:默认值只计算一次。这使得默认值是可变的对象如列表、字典或大部分类的实例时会有所不同。例如,下面的函数在后续调用过程中会累积传给它的参数:

def f(a, L=[]):
    L.append(a)
    return L
print f(1)
print f(2)
print f(3)

结果:

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

如果你不想默认值在随后的调用中共享,可以像这样编写函数:

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

结果:

[1]
[2]
[3]

4.7.2. 关键字参数

4.7.2. 关键字参数


函数也可以通过kwarg=value形式的关键字参数调用。例如,下面的函数:

接受一个必选参数( voltage)和三个可选参数( state, actiontype)。 可以用下列任意一种方式调用这个函数:





4.7.3.任意参数列表

4.7.4. 参数列表的分拆


4.7.5. lambda表达式


4.7.6. 文档字符串


4.8. 插曲:编码风格

既然要编写更长更复杂的 Python 代码, 这就要对其编码风格进行讨论了 。大多数语言可以编写成(或者更准确地说,被格式化成)不同风格的代码;其中一些会比其他的具有更好的可读性。让你的代码更易读一直是个好想法,而养成良好的编码风格对此益处良多。

对于 Python 而言, PEP 8 已成为大多数项目遵循的编码风格指南;它给出了一个高度可读,视觉友好的编码风格。每个 Python 开发者应该阅读一下;以下是其中的一些要点:

  • 使用 4 个空格的缩进,不要使用制表符。

    4 个空格是小缩进(允许更深的嵌套)和大缩进(易于阅读)之间很好的折衷。制表符会引起混乱,最好弃用。

  • 换行以确保一行的字符数不超过 79 个。

    这有助于小显示器用户阅读,也可以让大显示器能并排显示几个代码文件。

  • 使用空行分隔函数和类,以及函数内的大块代码。

  • 如果可能,注释独占一行。

  • 使用文档字符串。

  • 运算符周围和逗号后面使用空格,但是括号里侧不加空格: a = f(1, 2) + g(3, 4)

  • 保持类和函数的命名一致;通常是使用驼峰命名法命名类,使用下划线小写字母命名函数和方法 。始终使用self作为方法的第一个参数的名称(关于类和方法的更多信息,请参见初识类)。

  • 如果希望代码在全球环境中使用,不要使用奇特的编码。简单的 ASCII 在任何情况下永远工作得最好。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值