Python3 学习之流程控制

if 语句

1
2
3
4
5
6
7
8
9
10
11
if __name__ == '__main__':
x = int(input("please input an integer:"))
if x < 0:
x = 0
print("negative")
elif x == 0:
print("zero")
elif x == 1:
print("single")
else:
print("more")

for 循环

1
2
3
4
5
if __name__ == '__main__':
words = ["jpeg", "png", "gif"]
for w in words:
print(w, len(w))
print(words)

如果需要在遍历的过程中新增或者删除容器的元素,最好是对容器进行 copy 后,遍历 backup 容器,再对原来的容器修改,否则容易引起死循环。对一个列表做copy,简单如下(backupWords = words[:]

1
2
3
4
5
6
7
if __name__ == '__main__':
words = ["jpeg", "png", "gif"]
for w in words[:]:
print(w, len(w))
if len(w) > 3:
words.append(w)
print(words)

有个 range() 方法需要了解一下

当需要对数字做迭代的时候,例如Java中,我们经常这么做:for(int i = 0; i < 10; i++)。但在 python 中可以这么做:

1
2
3
if __name__ == '__main__':
for i in range(10):
print(i)

range() 方法也可以接收多个参数,来决定数字产生的范围是什么:

1
2
3
4
5
6
7
if __name__ == '__main__':
for i in range(10, 20): # 左闭右开
print(i, end=',')
for i in range(-10, -1): # 左闭右开
print(i, end=',')
for i in range(0, 100, 10): # 第三个参数是 step
print(i, end=',')

需要注意的是在python中,range(5)的返回值并不是一个数字列表,而是一个iterable的对象。直接print(range(5))的结果是“range(0, 5)”,这样的设计往往是考虑到节省空间,因为没有必要真的生成一个装有数字的列表。
list() 方法可以将一个 iterable 转为列表,了解一下:list(range(5))

流程跳转:break, continue, else

break 与 continue 与常规语言的行为一致,这里主要有个 else 语法需要了解一下:
一个 for 循环可以搭配一个 else 语句块,这个语句块的执行时机是:for 循环正常循环完毕,并且没有使用 break 中断循环。这个时候执行 else 语句块里的语句:

1
2
3
4
5
6
7
8
if __name__ == '__main__':
for n in range(2, 10):
for x in range(2, n):
if n % x == 0:
print(n, 'equals', x, '*', n // x)
break;
else:
print(n, " is a prime number")

输出结果为:

1
2
3
4
5
6
7
8
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

定义一个函数

1
2
3
4
5
6
7
8
9
10
def fib(n):
a, b = 0, 1
while a < n:
print(a, end=" ")
a, b = b, a + b # b = a + b, a不是新值
print()


if __name__ == "__main__":
fib(2000)

函数的参数传递

1
2
3
4
5
6
7
8
9
10
11
def ask_ok(prompt, retries = 4, reminder = "please try again"):
while True:
ok = input(prompt)
if ok in ("y", "yes"):
return True
if ok in ("no", "n"):
return False
retries = retries - 1
if retries < 0:
raise ValueError("invalid user response")
print(reminder)

如何调用这个方法,有三种方式:

  1. ask_ok(‘Do you really want to quit?’)
  2. ask_ok(‘OK to overwrite the file?’, 2)
  3. ask_ok(‘OK to overwrite the file?’, 2, ‘Come on, only yes or no!’)

retires 和 reminder 参数在方法声明时已经定义了默认值,若调用方法时不传这个参数,则采用默认值

参数的默认值可以从外部引用传递,例如:

1
2
3
4
5
6
7
L = 1

def from_out_side(prompt, arg = L):
print(prompt, arg)


L = 2

但这里的print方法打印出来的arg值是1, 因为参数的默认值定义一旦定义,则只会定义一次,无法通过外部修改值的方式去修改默认值(python属于值传递)
以下的代码就是个特别要注意的地方:

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

这段代码的输出结果是:

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

多次函数调用并不会使默认值L重新初始化,L的值只会初始化一次。后续对该函数的调用都用的是同一个L,即同一个列表。
如果不希望共享这个列表,那么可以通过以下这种方式做到:

1
2
3
4
5
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L

调用方法时,可以根据各个参数的下标位置,填入相应的值,例如func1(1,2,3),也可以直接指明参数名,例如 func(a=1, b=2, c=3)

可以使用 *arg 来代表不定长参数列表,也可以使用 **arg来代表不定长key-value对,具体用例如下所示:

1
2
3
4
5
6
7
8
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)
for kw in keywords:
print(kw, ":", keywords[kw])

调用方式如下所示:

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

结果输出如下:

1
2
3
4
5
6
7
8
-- 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.
----------------------------------------
shopkeeper : Michael Palin
client : John Cleese
sketch : Cheese Shop Sketch

一般情况下,可变参数列表或者参数key-value都是作为函数的最后一个参数的,如果函数的所有参数中,既包含可变参数也包含普通的参数,那么在可变参数后面的普通参数的声明必须带上参数名arg=””。调用的时候,也需要制定参数名,如下例子所示:

1
2
3
4
5
6
7
>>> def concat(*args, sep="/"):
... return sep.join(args)
...
>>> concat("earth", "mars", "venus")
'earth/mars/venus'
>>> concat("earth", "mars", "venus", sep=".")
'earth.mars.venus'

反过来,也可以通过 * 和 ** 来分解列表或者字典,然后传递给响应的函数作为参数,例子:

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

以及

1
2
3
4
5
6
7
8
>>> def parrot(voltage, state='a stiff', action='voom'):
... print("-- This parrot wouldn't", action, end=' ')
... print("if you put", voltage, "volts through it.", end=' ')
... print("E's", state, "!")
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

Lambda 表达式

1
2
3
4
5
6
7
8
>>> def make_incrementor(n):
... return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43

lambda表达式实际上定义了一个方法,make_incrementor 返回了一个 lambda 表达式,实际上我们认为它返回了一个方法。

beanlam wechat
欢迎订阅我的个人公众号
壕无人性