Skip to content

Python 运算符与流程控制语句

一、运算符

1. 算术运算符

python
a, b = 10, 3

print(a + b)    # 13   加法
print(a - b)    # 7    减法
print(a * b)    # 30   乘法
print(a / b)    # 3.3333333333333335  真除法(结果为浮点数)
print(a // b)   # 3    整除(地板除,向下取整)
print(a % b)    # 1    取余
print(a ** b)   # 1000 幂运算(10 的 3 次方)

# 负数的整除和取余
print(-7 // 2)   # -4  (向下取整,不是向零取整)
print(-7 % 2)    # 1   (结果符号与除数一致)
print(7 // -2)   # -4
print(7 % -2)    # -1

# 字符串和列表的 * 运算
print("ha" * 3)     # hahaha
print([0] * 5)      # [0, 0, 0, 0, 0]

2. 赋值运算符

python
# 基本赋值
x = 10

# 复合赋值运算符
x += 5     # x = x + 5  → 15
x -= 3     # x = x - 3  → 12
x *= 2     # x = x * 2  → 24
x /= 4     # x = x / 4  → 6.0
x //= 2    # x = x // 2 → 3.0
x %= 2     # x = x % 2  → 1.0
x **= 3    # x = x ** 3 → 1.0

print(x)   # 1.0

# 多变量赋值
a, b, c = 1, 2, 3
print(a, b, c)  # 1 2 3

# 连续赋值(指向同一个对象)
a = b = c = 100
print(a, b, c)  # 100 100 100

# 海象运算符 :=(Python 3.8+)
# 在表达式内部赋值
data = [1, 2, 3, 4, 5, 6, 7, 8]
if (n := len(data)) > 5:
    print(f"列表长度为 {n},超过 5 个元素")
# 列表长度为 8,超过 5 个元素

# 在 while 循环中使用
import random
while (num := random.randint(1, 10)) != 5:
    print(f"随机到了 {num},继续...")
print("随机到 5,结束!")

3. 比较运算符

python
a, b = 10, 20

print(a == b)    # False  等于
print(a != b)    # True   不等于
print(a > b)     # False  大于
print(a < b)     # True   小于
print(a >= b)    # False  大于等于
print(a <= b)    # True   小于等于

# 链式比较
x = 5
print(1 < x < 10)      # True   等价于 1 < x and x < 10
print(1 < x > 3)       # True   等价于 1 < x and x > 3
print(1 < x < 3)       # False

# 不同类型的比较
print(1 == 1.0)         # True  (int 和 float 可以比较)
print(1 == True)        # True  (True 等于 1)
print(0 == False)       # True  (False 等于 0)
print("abc" < "abd")    # True  (字符串按字典序比较)
print([1, 2] < [1, 3])  # True  (列表逐元素比较)

4. 逻辑运算符

python
# and / or / not
print(True and False)   # False
print(True or False)    # True
print(not True)         # False

# 短路求值
# and:第一个为 False 时直接返回,不再计算第二个
# or:第一个为 True 时直接返回,不再计算第二个
print(0 and 1/0)        # 0     (0 为假,直接返回 0,不会执行 1/0)
print(1 or 1/0)         # 1     (1 为真,直接返回 1)

# 返回值不一定是布尔值,而是决定结果的那个操作数
print(3 and 5)          # 5     (3 为真,继续看 5,返回 5)
print(0 and 5)          # 0     (0 为假,直接返回 0)
print(3 or 5)           # 3     (3 为真,直接返回 3)
print(0 or 5)           # 5     (0 为假,继续看 5,返回 5)
print("" or "default")  # default

# 利用短路特性设置默认值
name = ""
display_name = name or "匿名用户"
print(display_name)  # 匿名用户

# 优先级:not > and > or
print(True or False and False)    # True  (先算 and)
print((True or False) and False)  # False

5. 身份运算符(is / is not)

python
# is 判断两个变量是否指向同一个对象(比较内存地址)
# == 判断两个变量的值是否相等

a = [1, 2, 3]
b = [1, 2, 3]
c = a

print(a == b)     # True   值相等
print(a is b)     # False  不是同一个对象
print(a is c)     # True   c 和 a 指向同一个对象
print(id(a), id(b), id(c))  # a 和 c 的 id 相同,b 不同

# None 的判断推荐用 is
x = None
print(x is None)      # True  (推荐)
print(x == None)      # True  (不推荐,可能被 __eq__ 重写)

# 小整数缓存(CPython 实现细节)
# Python 会缓存 -5 到 256 之间的整数对象
a = 256
b = 256
print(a is b)     # True  (缓存范围内)

a = 257
b = 257
print(a is b)     # False 或 True(取决于运行环境,不应依赖此行为)

6. 成员运算符(in / not in)

python
# 列表
fruits = ["apple", "banana", "cherry"]
print("apple" in fruits)      # True
print("grape" in fruits)      # False
print("grape" not in fruits)  # True

# 字符串
text = "Hello, World!"
print("Hello" in text)    # True
print("hello" in text)    # False  (区分大小写)

# 字典(判断的是键,不是值)
person = {"name": "Alice", "age": 25}
print("name" in person)   # True
print("Alice" in person)  # False  (值不在检查范围内)
print(25 in person.values())  # True  (明确检查值)

# 集合
s = {1, 2, 3, 4, 5}
print(3 in s)     # True  (集合的 in 查找效率为 O(1))

# 元组
t = (10, 20, 30)
print(20 in t)    # True

7. 位运算符

python
a = 0b1010  # 10
b = 0b1100  # 12

# 按位与:对应位都为 1 才为 1
print(bin(a & b))    # 0b1000 (8)

# 按位或:对应位有一个为 1 就为 1
print(bin(a | b))    # 0b1110 (14)

# 按位异或:对应位不同为 1,相同为 0
print(bin(a ^ b))    # 0b110  (6)

# 按位取反
print(bin(~a))       # -0b1011 (-11)  (~x = -(x+1))

# 左移(相当于乘以 2 的 n 次方)
print(a << 1)   # 20  (10 * 2)
print(a << 2)   # 40  (10 * 4)

# 右移(相当于除以 2 的 n 次方,向下取整)
print(a >> 1)   # 5   (10 // 2)
print(a >> 2)   # 2   (10 // 4)

# 实用技巧
# 判断奇偶:n & 1
print(7 & 1)   # 1  (奇数)
print(8 & 1)   # 0  (偶数)

# 交换两个数(不用临时变量)
x, y = 3, 5
x ^= y
y ^= x
x ^= y
print(x, y)  # 5 3

8. 运算符优先级(从高到低)

优先级运算符说明
1**幂运算
2~ + -按位取反、正号、负号(一元运算符)
3* / // %乘、除、整除、取余
4+ -加、减
5<< >>左移、右移
6&按位与
7^按位异或
8|按位或
9== != > < >= <= is in比较、身份、成员
10not逻辑非
11and逻辑与
12or逻辑或
13:=海象运算符

不确定优先级时,使用括号 () 明确运算顺序,提高可读性。


二、流程控制语句

1. 条件语句(if / elif / else)

1.1 基本语法

python
# 基本 if
age = 18
if age >= 18:
    print("成年人")
# 成年人

# if-else
score = 55
if score >= 60:
    print("及格")
else:
    print("不及格")
# 不及格

# if-elif-else
score = 85
if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
elif score >= 70:
    grade = "C"
elif score >= 60:
    grade = "D"
else:
    grade = "F"
print(f"成绩等级:{grade}")
# 成绩等级:B

1.2 嵌套条件

python
age = 25
has_id = True

if age >= 18:
    if has_id:
        print("可以进入")
    else:
        print("请出示证件")
else:
    print("未成年,禁止进入")
# 可以进入

1.3 条件表达式(三元运算符)

python
age = 20
status = "成年" if age >= 18 else "未成年"
print(status)  # 成年

# 等价于
if age >= 18:
    status = "成年"
else:
    status = "未成年"

# 嵌套三元(不建议过度使用,影响可读性)
score = 85
grade = "A" if score >= 90 else "B" if score >= 80 else "C" if score >= 70 else "D"
print(grade)  # B

1.4 条件判断的简写技巧

python
# 判断变量是否为空/零/None
data = []
if not data:
    print("列表为空")
# 列表为空

# 多值匹配
color = "red"
if color in ("red", "green", "blue"):
    print("这是 RGB 颜色")
# 这是 RGB 颜色

# 使用 any() / all()
scores = [80, 90, 75, 60, 95]
if all(s >= 60 for s in scores):
    print("全部及格")
# 全部及格

if any(s >= 90 for s in scores):
    print("有人得了 90 分以上")
# 有人得了 90 分以上

2. match-case 语句(Python 3.10+)

结构化模式匹配,类似其他语言的 switch-case,但功能更强大。

2.1 基本匹配

python
command = "quit"

match command:
    case "start":
        print("启动程序")
    case "stop":
        print("停止程序")
    case "quit":
        print("退出程序")
    case _:          # _ 是通配符,匹配所有情况
        print("未知命令")
# 退出程序

2.2 多值匹配

python
status_code = 404

match status_code:
    case 200:
        print("OK")
    case 301 | 302:         # 使用 | 匹配多个值
        print("重定向")
    case 404:
        print("未找到")
    case 500 | 502 | 503:
        print("服务器错误")
    case _:
        print(f"状态码:{status_code}")
# 未找到

2.3 解构匹配

python
# 匹配序列
point = (3, 0)

match point:
    case (0, 0):
        print("原点")
    case (x, 0):
        print(f"在 X 轴上,x = {x}")
    case (0, y):
        print(f"在 Y 轴上,y = {y}")
    case (x, y):
        print(f"坐标:({x}, {y})")
# 在 X 轴上,x = 3

# 匹配字典
user = {"name": "Alice", "role": "admin"}

match user:
    case {"role": "admin", "name": name}:
        print(f"{name} 是管理员")
    case {"role": "user", "name": name}:
        print(f"{name} 是普通用户")
    case _:
        print("未知角色")
# Alice 是管理员

2.4 守卫条件(guard)

python
point = (3, 4)

match point:
    case (x, y) if x == y:
        print(f"在对角线上:({x}, {y})")
    case (x, y) if x > 0 and y > 0:
        print(f"在第一象限:({x}, {y})")
    case (x, y):
        print(f"其他位置:({x}, {y})")
# 在第一象限:(3, 4)

2.5 类型匹配

python
def process(value):
    match value:
        case int() as n if n > 0:
            print(f"正整数:{n}")
        case int() as n:
            print(f"非正整数:{n}")
        case str() as s:
            print(f"字符串:{s}")
        case list() as lst:
            print(f"列表,长度 {len(lst)}")
        case _:
            print(f"其他类型:{type(value)}")

process(42)        # 正整数:42
process(-1)        # 非正整数:-1
process("hello")   # 字符串:hello
process([1, 2])    # 列表,长度 2

3. 循环语句

3.1 for 循环

python
# 遍历列表
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)
# apple
# banana
# cherry

# 遍历字符串
for ch in "Python":
    print(ch, end=" ")
print()
# P y t h o n

# 使用 range()
for i in range(5):           # 0, 1, 2, 3, 4
    print(i, end=" ")
print()  # 0 1 2 3 4

for i in range(2, 8):        # 2, 3, 4, 5, 6, 7
    print(i, end=" ")
print()  # 2 3 4 5 6 7

for i in range(0, 10, 2):    # 步长为 2
    print(i, end=" ")
print()  # 0 2 4 6 8

for i in range(5, 0, -1):    # 倒序
    print(i, end=" ")
print()  # 5 4 3 2 1

# 使用 enumerate() 获取索引
languages = ["Python", "Java", "Go"]
for index, lang in enumerate(languages):
    print(f"{index}: {lang}")
# 0: Python
# 1: Java
# 2: Go

for index, lang in enumerate(languages, start=1):  # 索引从 1 开始
    print(f"{index}: {lang}")
# 1: Python
# 2: Java
# 3: Go

# 遍历字典
scores = {"Alice": 90, "Bob": 85, "Charlie": 92}
for name, score in scores.items():
    print(f"{name}: {score}")
# Alice: 90
# Bob: 85
# Charlie: 92

# 同时遍历多个序列:zip()
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
cities = ["Beijing", "Shanghai", "Shenzhen"]

for name, age, city in zip(names, ages, cities):
    print(f"{name}, {age}岁, {city}")
# Alice, 25岁, Beijing
# Bob, 30岁, Shanghai
# Charlie, 35岁, Shenzhen

# zip 以最短序列为准,zip_longest 以最长为准
from itertools import zip_longest
a = [1, 2, 3]
b = ["a", "b"]
for x, y in zip_longest(a, b, fillvalue="-"):
    print(x, y)
# 1 a
# 2 b
# 3 -

3.2 while 循环

python
# 基本 while
count = 0
while count < 5:
    print(count, end=" ")
    count += 1
print()
# 0 1 2 3 4

# 条件控制
password = ""
while password != "python123":
    password = input("请输入密码:")
print("登录成功!")

# 无限循环(配合 break 使用)
while True:
    cmd = input("输入命令(quit 退出):")
    if cmd == "quit":
        break
    print(f"执行命令:{cmd}")

3.3 break、continue 和 else

python
# break:立即终止整个循环
for i in range(10):
    if i == 5:
        break
    print(i, end=" ")
print()
# 0 1 2 3 4

# continue:跳过本次迭代,进入下一次
for i in range(10):
    if i % 2 == 0:
        continue
    print(i, end=" ")
print()
# 1 3 5 7 9

# for-else / while-else
# else 块在循环正常结束时执行,被 break 中断则不执行

# 查找质数
for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            break
    else:
        # 循环没有被 break,说明 n 是质数
        print(f"{n} 是质数")
# 2 是质数
# 3 是质数
# 5 是质数
# 7 是质数

# 搜索元素
target = 7
numbers = [2, 4, 6, 8, 10]
for num in numbers:
    if num == target:
        print(f"找到了 {target}")
        break
else:
    print(f"没有找到 {target}")
# 没有找到 7

3.4 嵌套循环

python
# 九九乘法表
for i in range(1, 10):
    for j in range(1, i + 1):
        print(f"{j}x{i}={i*j:2d}", end="  ")
    print()
# 1x1= 1
# 1x2= 2  2x2= 4
# 1x3= 3  2x3= 6  3x3= 9
# ...

# 打印三角形
n = 5
for i in range(1, n + 1):
    print(" " * (n - i) + "*" * (2 * i - 1))
#     *
#    ***
#   *****
#  *******
# *********

4. 推导式与生成器表达式

4.1 各类推导式

python
# 列表推导式
squares = [x ** 2 for x in range(1, 6)]
print(squares)  # [1, 4, 9, 16, 25]

# 带条件过滤
evens = [x for x in range(20) if x % 2 == 0]
print(evens)  # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# 带条件表达式
labels = ["偶" if x % 2 == 0 else "奇" for x in range(5)]
print(labels)  # ['偶', '奇', '偶', '奇', '偶']

# 嵌套循环
pairs = [(x, y) for x in range(3) for y in range(3) if x != y]
print(pairs)  # [(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)]

# 字典推导式
word = "hello"
char_count = {ch: word.count(ch) for ch in set(word)}
print(char_count)  # {'h': 1, 'e': 1, 'l': 2, 'o': 1}

# 集合推导式
nums = [1, -2, 3, -4, 5, -2, 3]
abs_unique = {abs(x) for x in nums}
print(abs_unique)  # {1, 2, 3, 4, 5}

4.2 生成器表达式

python
# 生成器表达式(用圆括号),惰性求值,节省内存
gen = (x ** 2 for x in range(1, 6))
print(type(gen))  # <class 'generator'>

# 逐个获取
print(next(gen))  # 1
print(next(gen))  # 4

# 遍历剩余
for val in gen:
    print(val, end=" ")
print()
# 9 16 25

# 实际应用:计算大数据的和(不需要创建完整列表)
total = sum(x ** 2 for x in range(1_000_000))
print(total)  # 333332833333500000

# 对比内存占用
import sys
list_comp = [x for x in range(10000)]
gen_expr = (x for x in range(10000))
print(sys.getsizeof(list_comp))  # 85176(约 83 KB)
print(sys.getsizeof(gen_expr))   # 200  (约 0.2 KB)

5. 异常处理

5.1 try-except 基本语法

python
# 捕获特定异常
try:
    result = 10 / 0
except ZeroDivisionError:
    print("除数不能为零")
# 除数不能为零

# 捕获异常信息
try:
    num = int("abc")
except ValueError as e:
    print(f"转换失败:{e}")
# 转换失败:invalid literal for int() with base 10: 'abc'

# 捕获多种异常
try:
    lst = [1, 2, 3]
    print(lst[10])
except IndexError:
    print("索引越界")
except TypeError:
    print("类型错误")
except Exception as e:
    print(f"其他错误:{e}")
# 索引越界

# 多个异常用元组
try:
    x = int("abc")
except (ValueError, TypeError) as e:
    print(f"输入错误:{e}")
# 输入错误:invalid literal for int() with base 10: 'abc'

5.2 try-except-else-finally

python
def divide(a, b):
    try:
        result = a / b
    except ZeroDivisionError:
        print("错误:除数不能为零")
        return None
    else:
        # 没有异常时执行
        print(f"{a} / {b} = {result}")
        return result
    finally:
        # 无论是否异常都会执行
        print("运算结束")

divide(10, 3)
# 10 / 3 = 3.3333333333333335
# 运算结束

divide(10, 0)
# 错误:除数不能为零
# 运算结束

5.3 常见内置异常

python
# ValueError     —— 值不合法
# TypeError      —— 类型不匹配
# IndexError     —— 索引越界
# KeyError       —— 字典键不存在
# FileNotFoundError —— 文件不存在
# ZeroDivisionError —— 除以零
# AttributeError —— 属性不存在
# ImportError     —— 导入模块失败
# StopIteration  —— 迭代器耗尽
# NameError      —— 变量未定义
# RuntimeError   —— 运行时错误

# 异常的继承关系
# BaseException
#  ├── SystemExit
#  ├── KeyboardInterrupt
#  └── Exception
#       ├── ValueError
#       ├── TypeError
#       ├── KeyError
#       ├── IndexError
#       ├── FileNotFoundError (OSError 的子类)
#       ├── ZeroDivisionError (ArithmeticError 的子类)
#       └── ...

5.4 主动抛出异常

python
def set_age(age):
    if not isinstance(age, int):
        raise TypeError("年龄必须是整数")
    if age < 0 or age > 150:
        raise ValueError(f"年龄超出合理范围:{age}")
    print(f"设置年龄为:{age}")

set_age(25)     # 设置年龄为:25

try:
    set_age(-1)
except ValueError as e:
    print(e)    # 年龄超出合理范围:-1

try:
    set_age("twenty")
except TypeError as e:
    print(e)    # 年龄必须是整数

5.5 自定义异常

python
class InsufficientFundsError(Exception):
    """余额不足异常"""
    def __init__(self, balance, amount):
        self.balance = balance
        self.amount = amount
        super().__init__(f"余额不足:当前 {balance},需要 {amount}")

class BankAccount:
    def __init__(self, balance=0):
        self.balance = balance

    def withdraw(self, amount):
        if amount > self.balance:
            raise InsufficientFundsError(self.balance, amount)
        self.balance -= amount
        return self.balance

account = BankAccount(100)
try:
    account.withdraw(150)
except InsufficientFundsError as e:
    print(e)                # 余额不足:当前 100,需要 150
    print(f"差额:{e.amount - e.balance}")  # 差额:50

6. 上下文管理器(with 语句)

python
# 基本用法:自动管理资源
with open("test.txt", "w") as f:
    f.write("Hello, World!")
# 文件在 with 块结束后自动关闭,即使发生异常也会关闭

# 等价于
f = open("test.txt", "w")
try:
    f.write("Hello, World!")
finally:
    f.close()

# 多个上下文管理器
with open("input.txt") as fin, open("output.txt", "w") as fout:
    content = fin.read()
    fout.write(content.upper())

# 自定义上下文管理器
class Timer:
    def __enter__(self):
        import time
        self.start = time.time()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        import time
        self.elapsed = time.time() - self.start
        print(f"耗时:{self.elapsed:.4f} 秒")
        return False  # 不抑制异常

with Timer():
    total = sum(range(1_000_000))
# 耗时:0.0312 秒

# 使用 contextlib 简化
from contextlib import contextmanager

@contextmanager
def timer(label="代码块"):
    import time
    start = time.time()
    yield
    elapsed = time.time() - start
    print(f"{label}耗时:{elapsed:.4f} 秒")

with timer("求和"):
    total = sum(range(1_000_000))
# 求和耗时:0.0312 秒

7. pass、assert 和 del

python
# pass —— 空操作占位符
def todo_function():
    pass  # 后续实现

class EmptyClass:
    pass

for i in range(10):
    if i % 2 == 0:
        pass  # 暂时不处理偶数
    else:
        print(i, end=" ")
print()
# 1 3 5 7 9

# assert —— 断言,条件为 False 时抛出 AssertionError
def calculate_average(numbers):
    assert len(numbers) > 0, "列表不能为空"
    return sum(numbers) / len(numbers)

print(calculate_average([1, 2, 3]))  # 2.0

try:
    calculate_average([])
except AssertionError as e:
    print(f"断言失败:{e}")
# 断言失败:列表不能为空

# 注意:assert 可以被 -O 参数禁用,不要用于生产环境的输入验证
# python -O script.py  会跳过所有 assert

# del —— 删除变量/元素
x = 42
del x
# print(x)  # NameError: name 'x' is not defined

lst = [1, 2, 3, 4, 5]
del lst[0]
print(lst)  # [2, 3, 4, 5]

del lst[1:3]
print(lst)  # [2, 5]

d = {"a": 1, "b": 2, "c": 3}
del d["b"]
print(d)  # {'a': 1, 'c': 3}

三、综合示例

示例 1:猜数字游戏

python
import random

number = random.randint(1, 100)
attempts = 0

print("猜数字游戏!范围 1-100")

while True:
    try:
        guess = int(input("请输入你的猜测:"))
    except ValueError:
        print("请输入一个有效的整数")
        continue

    attempts += 1

    if guess < number:
        print("太小了!")
    elif guess > number:
        print("太大了!")
    else:
        print(f"恭喜你猜对了!答案是 {number},你用了 {attempts} 次")
        break

示例 2:统计文本中的单词频率

python
text = "the quick brown fox jumps over the lazy dog the fox"

# 方法 1:使用字典
word_count = {}
for word in text.split():
    word_count[word] = word_count.get(word, 0) + 1

# 按频率降序排列
sorted_words = sorted(word_count.items(), key=lambda x: x[1], reverse=True)
for word, count in sorted_words:
    print(f"{word}: {count}")
# the: 3
# fox: 2
# quick: 1
# brown: 1
# jumps: 1
# over: 1
# lazy: 1
# dog: 1

# 方法 2:使用 collections.Counter
from collections import Counter
counter = Counter(text.split())
print(counter.most_common(3))  # [('the', 3), ('fox', 2), ('quick', 1)]

示例 3:矩阵转置

python
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
]

# 方法 1:嵌套循环
transposed = []
for j in range(len(matrix[0])):
    row = []
    for i in range(len(matrix)):
        row.append(matrix[i][j])
    transposed.append(row)

for row in transposed:
    print(row)
# [1, 4, 7]
# [2, 5, 8]
# [3, 6, 9]

# 方法 2:列表推导式
transposed = [[row[j] for row in matrix] for j in range(len(matrix[0]))]
print(transposed)  # [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

# 方法 3:zip 解包
transposed = [list(row) for row in zip(*matrix)]
print(transposed)  # [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

Released under the MIT License.