python学习总结4 - 流程控制工具
流程控制工具
1、if语句2、for语句3、range() 函数4、循环中的 break、continue 语句及 else 子句5、pass6、match语句(py3.10的内容)7、定义一个函数8、函数定义详解
8.1 默认值参数8.2 关键字参数8.3 特殊参数8.4 任意实参列表8.5 解包实参列表8.6 Lambda 表达式8.7 文档字符串8.8 函数注解 9、编码风格
流程控制工具 1、if语句x = int(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")
如果要把一个值与多个常量进行比较,或者检查特定类型或属性,match 语句更实用。
2、for语句迭代列表或字符串等任意序列,元素的迭代顺序与在序列中出现的顺序一致。 例如:
words = ['cat', 'window', 'defenestrate']
for w in words:
print(w, len(w))
C:Python39python.exe C:/Users/mc/Desktop/python基础/tiaoce.py cat 3 window 6 defenestrate 12
# Create a sample collection
users = {'Hans': 'active', 'Éléonore': 'inactive', '景太郎': 'active'}
print(users)
# Strategy: Iterate over a copy
for user, status in users.copy().items():
if status == 'inactive':
del users[user]
print(users)
users = {'Hans': 'active', 'Éléonore': 'inactive', '景太郎': 'active'}
active_users = {}
for user, status in users.items():
if status == 'active':
active_users[user] = status
print(active_users)
C:Python39python.exe C:/Users/mc/Desktop/python基础/tiaoce.py
{'Hans': 'active', 'Éléonore': 'inactive', '景太郎': 'active'}
{'Hans': 'active', '景太郎': 'active'}
{'Hans': 'active', '景太郎': 'active'}
3、range() 函数
for i in range(5):
print(i)
a = list(range(5,10))
print(a)
b = list(range(0, 10,3))
print(b)
c = list(range(-10, -100, -30))
print(c)
# 按索引迭代序列
a = ["mary", 'had', 'a', 'little']
for i in range(len(a)):
print(i, a[i])
# enumerate() 函数可以同时取出位置索引和对应的值:
for i, v in enumerate(a):
print(i, v)
range()返回的是可迭代对象,迭代时,该对象基于所需序列返回连续项,并没有生成真正的列表,从而节省了空间,这种对象称为可迭代对象 iterable
4、循环中的 break、continue 语句及 else 子句能够逐一返回其成员项的对象。 可迭代对象的例子包括所有序列类型 (例如 list, str 和 tuple) 以及某些非序列类型例如 dict, 文件对象 以及定义了 iter() 方法或是实现了 序列 语义的 getitem() 方法的任意自定义类对象。
可迭代对象被可用于 for 循环以及许多其他需要一个序列的地方(zip()、map() …)。当一个可迭代对象作为参数传给内置函数 iter() 时,它会返回该对象的迭代器。这种迭代器适用于对值集合的一次性遍历。在使用可迭代对象时,你通常不需要调用 iter() 或者自己处理迭代器对象。for 语句会为你自动处理那些操作,创建一个临时的未命名变量用来在循环期间保存迭代器。参见 iterator、sequence 以及 generator。
break 用于跳出最近的 for 或 while 循环,与 if 语句相比,循环的 else 子句更像 try 的 else 子句: try 的 else 子句在未触发异常时执行,循环的 else 子句则在未运行 break 时执行。try 语句和异常详见 异常的处理。
for n in range(1, 10):
for x in range(2,n):
if n % x == 0:
print(f"找到符合if的{n,x},了,后面就退出了循环查找的操作")
break
else:
print("没有执行break的时候,就执行else语句")
C:Python39python.exe C:/Users/mc/Desktop/python基础/tiaoce.py 没有执行break的时候,就执行else语句 没有执行break的时候,就执行else语句 没有执行break的时候,就执行else语句 找到符合if的(4, 2),了,后面就退出了循环查找的操作 没有执行break的时候,就执行else语句 找到符合if的(6, 2),了,后面就退出了循环查找的操作 没有执行break的时候,就执行else语句 找到符合if的(8, 2),了,后面就退出了循环查找的操作 找到符合if的(9, 3),了,后面就退出了循环查找的操作
for n in range(1, 10):
print(f"{n}开始查找")
for x in range(2,n):
if n % x == 0:
print(f"找到符合if的{n,x},了,后面有continue,还会在for的迭代中继续找")
continue
else:
print("没有执行break的时候,就执行else语句")
C:Python39python.exe C:/Users/mc/Desktop/python基础/tiaoce.py 1开始查找 没有执行break的时候,就执行else语句 2开始查找 没有执行break的时候,就执行else语句 3开始查找 没有执行break的时候,就执行else语句 4开始查找 找到符合if的(4, 2),了,后面有continue,还会在for的迭代中继续找 没有执行break的时候,就执行else语句 5开始查找 没有执行break的时候,就执行else语句 6开始查找 找到符合if的(6, 2),了,后面有continue,还会在for的迭代中继续找 找到符合if的(6, 3),了,后面有continue,还会在for的迭代中继续找 没有执行break的时候,就执行else语句 7开始查找 没有执行break的时候,就执行else语句 8开始查找 找到符合if的(8, 2),了,后面有continue,还会在for的迭代中继续找 找到符合if的(8, 4),了,后面有continue,还会在for的迭代中继续找 没有执行break的时候,就执行else语句 9开始查找 找到符合if的(9, 3),了,后面有continue,还会在for的迭代中继续找 没有执行break的时候,就执行else语句 Process finished with exit code 05、pass
pass 语句不执行任何操作。语法上需要一个语句,但程序不实际执行任何动作时,可以使用该语句。例如
def initlog(*args):
pass
# 创建了一个最小的类
class MyEmptyClass:
pass
while True:
pass
6、match语句(py3.10的内容)
简单介绍如下,详细内容你可以参阅以教程格式撰写的 PEP 636
- 如果要把一个值与多个常量进行比较,或者检查特定类型或属性,match 语句更实用
status = 404
def http_error(status):
match status:
case 400:
return "Bad request"
case 401 | 403 | 404: # or 关系
return "not allowed"
case 404:
return "Not found"
case 418:
return "I'm a teapot"
case _:
return "Something's wrong with the internet"
最后一个代码块:“变量名” _ 被作为 通配符 并必定会匹配成功。 如果没有 case 语句匹配成功,则不会执行任何分支。
- 绑定变量
point = (x, y)
match point:
case (0, 0):
print("Origin")
case (0, y):
print(f"Y={y}")
case (x, 0):
print(f"X={x}")
case (x, y):
print(f"X={x}, Y={y}")
case _:
raise ValueError("Not a point")
- 使用类实现数据结构,可在类名后加一个类似于构造器的参数列表,这样做可以把属性放到变量里
class Point:
x: int
y: int
def where_is(point):
match point:
case Point(x=0, y=0):
print("Origin")
case Point(x=0, y=y):
print(f"Y={y}")
case Point(x=x, y=0):
print(f"X={x}")
case Point():
print("Somewhere else")
case _:
print("Not a point")
def where_is(point):
match points:
case []:
print("No points")
case [Point(0, 0)]:
print("The origin")
case [Point(x, y)]:
print(f"Single point {x}, {y}")
case [Point(0, y1), Point(0, y2)]:
print(f"Two on the Y axis at {y1}, {y2}")
case _:
print("Something else")
def where_is(point):
match point:
case Point(x, y) if x == y:
print(f"Y=X at {x}")
case Point(x, y):
print(f"Not on the diagonal")
- 模式可以使用命名常量。 这些命名常量必须为带点号的名称以防止它们被解读为捕获变量
from enum import Enum
class Color(Enum):
RED = 'red'
GREEN = 'green'
BLUE = 'blue'
color = Color(input("Enter your choice of 'red', 'blue' or 'green': "))
match color:
case Color.RED:
print("I see red!")
case Color.GREEN:
print("Grass is green")
case Color.BLUE:
print("I'm feeling the blues :(")
7、定义一个函数
斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列1、1、2、3、5、8、13、21、34、……,这个数列从第3项开始,每一项都等于前两项之和。在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用
def fib2(n):
"""可以输出限定数值内的斐波那契数列函数"""
result = []
a, b = 0, 1
while a < n:
result.append(a)
a, b = b ,a+b
return result
f100 = fib2(100)
print(f100)
C:Python39python.exe C:/Users/mc/Desktop/python基础/tiaoce.py [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
return 语句不带表达式参数时,返回 None。函数执行完毕退出也返回 None
8、函数定义详解 8.1 默认值参数为参数指定默认值是非常有用的方式。调用函数时,可以使用比定义时更少的参数
def ask_ok(prompt, retries=4, reminder='Please try again!'):
while True:
ok = 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 ValueError('invalid user response')
print(reminder)
# ask_ok('Do you really want to quit?')
# ask_ok('OK to overwrite the file?', 2)
ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')
C:Python39python.exe C:/Users/mc/Desktop/python基础/tiaoce.py OK to overwrite the file?jiao Come on, only yes or no! OK to overwrite the file?
默认值只计算一次。默认值为列表、字典或类实例等可变对象时,会产生与该规则不同的结果。例如,下面的函数会累积后续调用时传递的参数
def f(a, L=[]):
L.append(a)
return L
print(f(1))
print(f(2))
print(f(3))
C:Python39python.exe C:/Users/mc/Desktop/python基础/tiaoce.py
[1]
[1, 2]
[1, 2, 3]
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
print(f(1))
print(f(2))
print(f(3))
C:Python39python.exe C:/Users/mc/Desktop/python基础/tiaoce.py
[1]
[2]
[3]
8.2 关键字参数
函数调用时,关键字参数必须跟在位置参数后面,关键字参数的顺序并不重要。这也包括必选参数
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
print("-- This parrot wouldn't", action, end=' ')
print("if you put", voltage, "volts through it.")
print("-- Lovely plumage, the", type)
print("-- It's", state, "!")
# 函数调用
parrot(1000)
parrot(voltage=1000)
parrot(voltage=1000000, action='VOOOOOM')
parrot(action='VOOOOOM', voltage=1000000)
parrot('a million', 'bereft of life', 'jump')
parrot('a thousand', state='pushing up the daisies')
当参数中带有星号时候,*name 必须在 **name 前面), *name 形参接收一个元组,该字典包含与函数中已定义形参对应之外的所有关键字参数(把位置参数后面的参数打包成元组),**name 形式时,接收一个字典
def cheeseshop(kind, *arguments, **keywords):
print(f"-- Do you have any {kind}?")
print(f"-- 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])
cheeseshop("Limburger",
"It's very runny, sir.",
"It's really very, VERY runny, sir.",
shopkeeper="Michael Palin",
client="John Cleese",
sketch="Cheese Shop Sketch")
C:Python39python.exe C:/Users/mc/Desktop/python基础/tiaoce.py
-- 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
8.3 特殊参数
使用仅限位置形参,可以让用户无法使用形参名。形参名没有实际意义时,强制调用函数的实参顺序时,或同时接收位置形参和关键字时,这种方式很有用。当形参名有实际意义,且显式名称可以让函数定义更易理解时,阻止用户依赖传递实参的位置时,才使用关键字。对于 API,使用仅限位置形参,可以防止未来修改形参名时造成破坏性的 API 变动。
def combined_example(pos_only, /, standard, *, kwd_only): print(pos_only, standard, kwd_only)
- 默认情况下,参数可以按位置或显式关键字传递给 Python 函数,/和*就是为了限制默认情况斜杠前的参数 pos_only
# 只能被这样调用 combined_example(1, /, standard, *, kwd_only) # 不能使用关键字调用 combined_example(pos_only=1 /, standard, *, kwd_only)
- 斜杠星号中间的 standard
# 只能被这样调用 combined_example(pos_only, /, 1, *, kwd_only) # 也能使用关键字调用 combined_example(pos_only /, standard=1, *, kwd_only)
- 星号后面的 kwd_only
# 不能被这样调用 combined_example(pos_only, /, standard, *, 1) # 只能使用关键字调用 combined_example(pos_only /, standard, *, kwd_only=1)
完整示例:
def combined_example(pos_only, /, standard, *, kwd_only): print(pos_only, standard, kwd_only) # 调用函数 combined_example(1, 2, kwd_only=3) combined_example(1, standard=2, kwd_only=3)8.4 任意实参列表
调用函数时,使用任意数量的实参是最少见的选项
def concat(*args, sep="/"):
return sep.join(args)
a = concat("earch", "mars", "venv")
print(a)
C:Python39python.exe C:/Users/mc/Desktop/python基础/tiaoce.py
earch/mars/venv
8.5 解包实参列表
用 * 操作符把实参从列表、元组解包出来
a = list(range(3, 6)) print(a) # [3, 4, 5] args = [3, 4] b = list(range(*(args))) # 把 [a,b] 变成 a,b print(b) # [3, 4, 5]
字典可以用 操作符** 传递关键字参数
def parrot(voltage, state='a stiff', action='voom'):
print(f"-- This parrot wouldn't {action}", end=' ')
print(f"if you put {voltage} volts through it.", end=' ')
print(f"E's {state} !")
d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
parrot(**d)
C:Python39python.exe C:/Users/mc/Desktop/python基础/tiaoce.py
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !
8.6 Lambda 表达式
lambda 关键字用于创建小巧的匿名函数。lambda a, b: a+b 函数返回两个参数的和,Lambda 函数可用于任何需要函数对象的地方。在语法上,匿名函数只能是单个表达式。
lambda 函数可以引用包含作用域中的变量,函数make返回一个lambda函数(匿名函数):
def make_incrementor(n):
return lambda x: x + n
f1 = make_incrementor(42)
a = f1(10)
print(a)
C:Python39python.exe C:/Users/mc/Desktop/python基础/tiaoce.py
52
把匿名函数用作传递的实参 8.7 文档字符串
第一行应为对象用途的简短摘要。为保持简洁,不要在这里显式说明对象名或类型,第一行通常与字符串开头的引号相邻文档字符串为多行时,第二行应为空白行,后面的行可包含若干段落,描述对象的调用约定、副作用等,字符串前面不应使用tab,通常为8个空格
def my_function():
"""Do nothing, but document it.
No, really, it doesn't do anything.
"""
pass
print(my_function.__doc__)
C:Python39python.exe C:/Users/mc/Desktop/python基础/tiaoce.py
Do nothing, but document it.
No, really, it doesn't do anything.
8.8 函数注解
针对函数形参或返回值的标注,函数标注通常用于 类型提示:例如以下函数预期接受两个 int 参数并预期返回一个 int 值,另请参阅 对象注解属性的最佳实践 以了解使用标的最佳实践。
def sum_two_numbers(a: int, b: int) -> int: return a + b
标注 以字典的形式存放在函数的 annotations 属性中,并且不会影响函数的任何其他部分。 形参标注的定义方式是在形参名后加冒号,后面跟一个表达式,该表达式会被求值为标注的值。 返回值标注的定义方式是加组合符号 ->,后面跟一个表达式,该标注位于形参列表和表示 def 语句结束的冒号之间。 下面的示例有一个必须的参数,一个可选的关键字参数以及返回值都带有相应的标注:
def f(ham: str, eggs: str = 'eggs') -> str:
print('annootations:', f.__annotations__)
print('arguments:', ham, eggs)
return ham + 'and' + eggs
f('spam')
9、编码风格
Python 项目大多都遵循 PEP 8 的风格指南,以下是该提案中的核心要点:
缩进,用 4 个空格,不要用制表符。4 个空格是小缩进(更深嵌套)和大缩进(更易阅读)之间的折中方案。制表符会引起混乱,最好别用。换行,一行不超过 79 个字符。这样换行的小屏阅读体验更好,还便于在大屏显示器上并排阅读多个代码文件。用空行分隔函数和类,及函数内较大的代码块。最好把注释放到单独一行。使用文档字符串。运算符前后、逗号后要用空格,但不要直接在括号内使用: a = f(1, 2) + g(3, 4)。类和函数的命名要一致;按惯例,命名类用 UpperCamelCase,命名函数与方法用 lowercase_with_underscores。命名方法中第一个参数总是用 self (类和方法详见 初探类)。编写用于国际多语环境的代码时,不要用生僻的编码。Python 默认的 UTF-8 或纯 ASCII 可以胜任各种情况。同理,就算多语阅读、维护代码的可能再小,也不要在标识符中使用非 ASCII 字符。



