4. 控制流#

4.1. if语句#

x = int(input("请输入一个数字:"))
---------------------------------------------------------------------------
StdinNotImplementedError                  Traceback (most recent call last)
Cell In[1], line 1
----> 1 x = int(input("请输入一个数字:"))

File ~/myenv/lib/python3.10/site-packages/ipykernel/kernelbase.py:1281, in Kernel.raw_input(self, prompt)
   1279 if not self._allow_stdin:
   1280     msg = "raw_input was called, but this frontend does not support input requests."
-> 1281     raise StdinNotImplementedError(msg)
   1282 return self._input_request(
   1283     str(prompt),
   1284     self._parent_ident["shell"],
   1285     self.get_parent("shell"),
   1286     password=False,
   1287 )

StdinNotImplementedError: raw_input was called, but this frontend does not support input requests.
if x< 0:
    x = 0
    print("小于零")
elif x == 0:
    print("等于0")
else:
    print("大于零")
大于零

4.2. for语句#

## 迭代列表

animals = ['cat', 'dog', 'lion']
for a in animals:
    print(a, len(a))
cat 3
dog 3
lion 4
## 迭代字典
users = {'Hans': 'active', 'Éléonore': 'inactive', '景太郎': 'active'}
for user, status in users.items():
    print(user, status)
Hans active
Éléonore inactive
景太郎 active
## 通过索引迭代列表

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.3. break 和 continue 语句#

break 语句将跳出最近的一层 for 或 while 循环:

for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print(f"{n} equals {x} * {n//x}")
            break
4 equals 2 * 2
6 equals 2 * 3
8 equals 2 * 4
9 equals 3 * 3

continue 语句将继续执行循环的下一次迭代:

for num in range(2, 10):
    if num % 2 == 0:
        print(f"Found an even number {num}")
        continue
    print(f"Found an odd number {num}")
Found an even number 2
Found an odd number 3
Found an even number 4
Found an odd number 5
Found an even number 6
Found an odd number 7
Found an even number 8
Found an odd number 9

4.4. 循环的 else 子句#

在 for 或 while 循环中 break 语句可能对应一个 else 子句。 如果循环在未执行 break 的情况下结束,else 子句将会执行。

在 for 循环中,else 子句会在循环结束其他最后一次迭代之后,即未执行 break 的情况下被执行。

在 while 循环中,它会在循环条件变为假值后执行。

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

4.5. pass语句#

pass 语句不执行任何动作。语法上需要一个语句,但程序毋需执行任何动作时,可以使用该语句。

# 创建一个最小的类
class MyEmptyClass:
    pass
# pass 还可用作函数或条件语句体的占位符
def initlog(*args):
    pass   # 记得实现这个!

4.6. match语句#

match 语句接受一个表达式并把它的值与一个或多个 case 块给出的一系列模式进行比较。

def http_error(status):
    match status:
        case 400:
            return "Bad request"
        case 404:
            return "Not found"
        case 418:
            return "I'm a teapot"
        case 401 | 403 | 404: # 可以使用 | (“ or ”)在一个模式中组合几个字面值
            return "Not allowed"
        case _: # 变量名” _ 被作为 通配符 并必定会匹配成功
            return "Something's wrong with the internet"
print(http_error(401))
Not allowed

形如解包赋值的模式可被用于绑定变量:

def point_fn(point):
    # 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")
point_fn((0,0))
point_fn((0, 1))
point_fn((100, 0))
point_fn((1, 2))
Origin
Y=1
X=100
X=1, Y=2

将对象属性捕获到变量里面:

# 定义类
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

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(x, y) if x == y: # 添加if字句作为约束项
        #     print(f"Y=X at {x}")
        case Point():
            print("Somewhere else")
        case _:
            print("Not a point")

where_is(Point(0,0))
where_is(Point(0, 1))
where_is(Point(1, 0))
where_is(Point(1, 1))
where_is(100)
Origin
Y=1
X=1
Somewhere else
Not a point

模式可以使用具名常量。它们必须作为带点号的名称出现,以防止它们被解释为用于捕获的变量:

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 :(")
I see red!