首页/Python 与数据实践/变量、表达式与流程控制
Python 与数据实践 · 第 02 章

变量、表达式与流程控制

上一章环境已经跑通,从这一章开始正式写代码。我们要解决三件事:数据怎么存(变量)、数据怎么算(运算符与表达式)、程序怎么根据不同情况走不同的路、怎么重复干活(流程控制)。这三样是所有 Python 代码的地基,务必敲熟

约 27 分钟10,881 字28 个代码示例

上一章环境已经跑通,从这一章开始正式写代码。我们要解决三件事:数据怎么存(变量)、数据怎么算(运算符与表达式)、程序怎么根据不同情况走不同的路、怎么重复干活(流程控制)。这三样是所有 Python 代码的地基,务必敲熟。

一、先摸清 Python 的脾气

动手之前,先用四个标签认识一下这门语言:

  • 解释型:代码不用事先编译成机器码,解释器读一句执行一句,改完立刻见效
  • 动态类型:变量本身不锁定类型,同一个名字这一秒装数字、下一秒装字符串都没问题
  • 强类型:类型不合时 Python 绝不偷偷帮你乱转,"3" + 5 会直接报错——宁可报错,也不瞎猜
  • 面向对象:万物皆对象,连数字、字符串、函数身上都挂着属性和方法

二、注释:写给读代码的人

# 井号开头,从这里到行尾都归注释管

"""
三个双引号包起来的整块内容
想写几行就写几行
"""

'''
三个单引号也行
效果完全一样
'''

注释是给人看的,解释器会直接无视它。养成"写代码顺手写注释"的习惯,三个月后的你会感谢现在的你。

三、变量:给数据贴标签

创建变量

Python 里造一个变量不需要提前声明类型,起个名字、直接赋值,它就诞生了:

shop = "山野茶铺"    # 字符串
tables = 12         # 整数
rating = 4.8        # 浮点数
is_open = True      # 布尔值

可以把变量理解成贴在数据上的标签:标签本身没有类型,贴到什么数据上,它就代表什么。

起名的硬性规则

规则 具体要求 示例
开头有限制 只能以字母或下划线打头 tea_name、_count
内容有限制 只能由字母、数字、下划线组成 order2、cup_500
大小写敏感 Name 和 name 是两个不同的变量 Name = 1、name = 2
避开关键字 Python 保留的字不能占用 if、for、class

关键字清单(这些名字归 Python 所有): False, None, True, and, as, assert, async, await, break, class, continue, def, del, elif, else, except, finally, for, from, global, if, import, in, is, lambda, nonlocal, not, or, pass, raise, return, try, while, with, yield

# 合法的命名
tea_name = "鸭屎香柠檬茶"
_total = 0
MAX_CUPS = 500
order2 = 88.5

# 不合法的命名(写了就报错)
# 2order = 10        # 数字打头,不行
# tea-name = "绿茶"  # 中间那根横线会被当成减号
# for = 5            # for 是关键字,被 Python 占了

起名的软性约定

规则是底线,约定是品味。Python 社区有一套默认的命名习惯:

场景 惯例 示例
普通变量 小写加下划线(snake_case) order_count、total_price
常量 全大写加下划线 MAX_STOCK、PI
类名 大驼峰(PascalCase) OrderDetail、ShopModel
私有/内部变量 下划线开头 _helper、__secret

一行搞定多个赋值

# 一行创建多个变量
lemon, oolong, jasmine = 12, 30, 8

# 交换两个变量的值(不需要第三个变量打辅助)
cup_a, cup_b = "奶茶", "果茶"
cup_a, cup_b = cup_b, cup_a  # cup_a="果茶",cup_b="奶茶"

# 一串变量共用同一个值
sugar = spice = ice = "标准"

四、数据类型:认一认都有什么

六大类基本类型

分类 类型 长什么样 要点
数字 ==int== 7, -20, 0 没有大小上限,多大都装得下
数字 ==float== 3.5, -0.2, 6e8 双精度浮点数
数字 complex 2+3j, 1-1j 虚数单位用 j 表示 $\sqrt{-1}$
数字/布尔 ==bool== True, False 本质是 int:True 就是 1,False 就是 0
文本 ==str== '奶茶', "tea" 引号包起来的都是字符串
空值 ==NoneType== None 表示"什么都没有"
容器 list 等 [1, 2]、(3, 4) 第 03 章专门展开

原子与容器两大阵营

  • 原子类型(也叫基本内置类型、标量类型):一个值就是一个不可拆的整体——int、float、complex、bool、str、NoneType
  • 容器类型:一个值里面装着一堆别的值——list、tuple 等,第 03 章细说

字面量的各种写法

# 整数:支持不同进制
print(2026)      # 十进制
print(0b1100)    # 二进制,等于 12
print(0o17)      # 八进制,等于 15
print(0xFF)      # 十六进制,等于 255

# 浮点数:小数形式与科学计数法
print(9.8)       # 常规小数
print(-2.5)      # 负的小数
print(3.0e8)     # 科学计数法 = 300000000.0
print(6.1e-2)    # 负指数 = 0.061

# 布尔值只有两个
print(True)      # 真
print(False)     # 假

# 字符串:单引号双引号等价,三引号能跨行
print("双引号可以")
print('单引号也行')
print('''跨越
两行''')
print("""同样
两行""")

# 空值
print(None)

五、type():随时验明正身

拿不准一个值是什么类型,扔给 type() 看一眼:

# 整数
print(type(2026))    # <class 'int'>
print(type(0b1100))  # <class 'int'>
print(type(0o17))    # <class 'int'>
print(type(0xFF))    # <class 'int'>

# 浮点数
print(type(9.8))     # <class 'float'>
print(type(-2.5))    # <class 'float'>
print(type(3.0e8))   # <class 'float'>
print(type(6.1e-2))  # <class 'float'>

# 布尔值
print(type(True))    # <class 'bool'>
print(type(False))   # <class 'bool'>

# 字符串
print(type("茶"))    # <class 'str'>
print(type('Tea'))   # <class 'str'>

# 空值
print(type(None))    # <class 'NoneType'>

注意一个细节:type() 返回的不是一串文字,而是类型对象本身,所以可以直接拿去和类型比较:

print(type(2026) == int)  # True

六、类型转换:让数据换个身份

# 字符串 → 整数
count_str = "36"
count = int(count_str)      # 36

# 整数 → 字符串
price = 22
price_str = str(price)      # "22"

# 整数 → 浮点数
seats = 40
seats_float = float(seats)  # 40.0

# 浮点数 → 整数(直接砍掉小数部分,不做四舍五入)
discount = 0.75
print(int(discount))        # 0

# 任何值 → 布尔值
print(bool(0))       # False
print(bool(3))       # True
print(bool(""))      # False
print(bool("茶"))    # True

七、f-string:把变量嵌进字符串

从 Python 3.6 起,字符串前面挂一个 f(或 F),它就变成了"模板"——花括号 {} 里的内容会被现场计算、再填回字符串。这是目前最简洁也最主流的格式化方式,先掌握它就够了。

drink = "生椰拿铁"
price = 18
print(f"饮品:{drink},价格:{price} 元")  # 饮品:生椰拿铁,价格:18 元

# 花括号里可以直接写表达式
cups = 3
print(f"{cups} 杯共 {cups * price} 元")   # 3 杯共 54 元

八、输入与输出

print:向屏幕说话

# 输出一句话
print("欢迎光临")

# 一次输出多项,默认用空格隔开
print("库存:", 36)

# 用 sep 自定义分隔符
print("2026", "08", "27", sep="-")  # 2026-08-27

# 用 end 自定义结尾(默认是换行)
print("正在备餐", end="...")
print("完成")  # 正在备餐...完成

input:听用户说

# input 拿到的东西永远是字符串
city = input("请输入你所在的城市:")
print("收到,", city)

# 想当数字用,必须先手动转换
height_str = input("请输入身高(厘米):")
height = int(height_str)
print("换个说法是", height / 100, "米")

九、运算符全家福

算术运算符

运算符 作用 int float str bool None
+ 加 数值相加 数值相加 拼接 按数字算 ✗
- 减 数值相减 数值相减 ✗ 按数字算 ✗
* 乘 数值相乘 数值相乘 重复若干遍 按数字算 ✗
/ 除 结果是 float 结果是 float ✗ 按数字算 ✗
// 整除 向下取整 向下取整 ✗ 按数字算 ✗
% 取余 求余数 求余数 ✗ 按数字算 ✗
** 乘方 幂运算 幂运算 ✗ 按数字算 ✗
# 整数运算
print(16 + 5)     # 21
print(16 - 5)     # 11
print(16 * 5)     # 80
print(16 / 5)     # 3.2(注意:/ 的结果一定是 float)
print(16 // 5)    # 3(只留整数部分)
print(16 % 5)     # 1(余数)
print(16 ** 5)    # 1048576

# 浮点数运算
print(4.0 + 1.5)   # 5.5
print(4.0 - 1.5)   # 2.5
print(4.0 * 1.5)   # 6.0
print(4.0 / 1.5)   # 2.666...
print(4.0 // 1.5)  # 2.0
print(4.0 % 1.5)   # 1.0
print(4.0 ** 1.5)  # 8.0

# 字符串只吃两个运算符
print("芋泥" + "波波")   # 芋泥波波(拼接)
print("好喝!" * 3)       # 好喝!好喝!好喝!(重复)

# 布尔值本质是 0 和 1
print(True + True)   # 2
print(False * 9)     # 0

# None 参与任何算术运算都会报错
# print(None - 1)    # TypeError

比较运算符

运算符 含义 int / float str bool None
== 等于 比数值 比内容 True==1、False==0 只与 None 相等
!= 不等于 比数值 比内容 同上 与非 None 都不等
< > <= >= 比大小 比数值 按字典序 按 0/1 比 ✗ 会报错
# 数字比较
print(8 == 8)        # True
print(8 != 5)        # True
print(8 > 5)         # True

# 浮点数同理
print(7.5 >= 7.5)    # True
print(7.5 < 7.0)     # False

# 字符串按字典序逐个字符比编码
print("tea" == "tea")     # True
print("tea" != "coffee")  # True
print("apple" < "banana") # True
print("B" < "b")          # True(大写 B=66,小写 b=98)

# 布尔值当数字比
print(True == 1)     # True
print(False == 0)    # True
print(True > False)  # True

# None 只能判断"是不是它"
print(None == None)  # True
print(None != 0)     # True
print(None != False) # True
# print(None > 0)    # TypeError

链式比较

Python 支持把比较运算符像数学不等式一样连着写:

temperature = 26

# 其他语言的常规写法
print(temperature > 0 and temperature < 35)  # True

# Python 的链式写法,更顺眼
print(0 < temperature < 35)     # True
print(20 <= temperature < 30)   # True
print(0 < temperature < 10)     # False

# 想连更多个也没问题
print(0 < temperature < 35 < 100)  # True

等价规则: a < b < c 相当于 a < b and b < c,区别在于 b 只计算一次。

赋值运算符

写法 相当于 常用于
n = 5 - 所有类型
n += 2 n = n + 2 数字、字符串
n -= 2 n = n - 2 数字
n *= 2 n = n * 2 数字、字符串
n /= 2 n = n / 2 数字
n //= 2 n = n // 2 数字
n %= 2 n = n % 2 数字
n **= 2 n = n ** 2 数字
# 数值的累计
total = 20
total += 8   # 28
total -= 3   # 25
total *= 2   # 50
total /= 5   # 10.0(注意:一用 /,结果就变 float)

# 字符串同样支持 += 和 *=
order = "一份炸鸡"
order += ",加辣"   # 一份炸鸡,加辣
order *= 2          # 一份炸鸡,加辣一份炸鸡,加辣

海象运算符(:=)

Python 3.8 引入的赋值表达式,能把"赋值"和"求值"塞进同一行。

# 老写法:先赋值,再进循环判断
reply = input("输入点什么(exit 退出):")
while reply != "exit":
    print(f"你说的是:{reply}")
    reply = input("输入点什么(exit 退出):")

# 海象写法:赋值和判断合二为一
while (reply := input("输入点什么(exit 退出):")) != "exit":
    print(f"你说的是:{reply}")

注意: 这是 3.8 才有的特性,更老的版本跑不了。

逻辑运算符

运算符 名字 结果怎么定
and 与 前面是假 → 返回前面;否则返回后面
or 或 前面是真 → 返回前面;否则返回后面
not 非 永远返回 True / False

各类型的真假值( falsy 判定): - int:0 为假,其余为真 - float:0.0 为假,其余为真 - str:"" 为假,其余为真 - bool:False 为假 - NoneType:None 为假

# 数字
print(0 and 6)        # 0(0 是假,直接返回 0)
print(4 and 6)        # 6(4 是真,返回后面)
print(0 or 6)         # 6
print(4 or 6)         # 4
print(not 0)          # True
print(not 6)          # False

# 浮点数
print(0.0 and 6.0)    # 0.0
print(4.0 and 6.0)    # 6.0
print(not 0.0)        # True

# 字符串
print("" and "abc")   # ""(空字符串算假)
print("hi" and "abc") # "abc"
print(not "")         # True
print(not "abc")      # False

# 布尔值
print(True and False) # False
print(True or False)  # True
print(not True)       # False

# None
print(None and True)  # None
print(None or True)   # True
print(not None)       # True

三元表达式(条件表达式)

if-else 的单行浓缩版,适合在两种值之间快速二选一:

# 语法
结果 = 值A if 条件 else 值B
stock = 42

# 常规写法
if stock >= 30:
    status = "库存充足"
else:
    status = "需要补货"

# 三元写法(一行搞定)
status = "库存充足" if stock >= 30 else "需要补货"
print(status)  # 库存充足

# 也能嵌套,但别贪多
points = 4200
level = "金卡" if points >= 5000 else ("银卡" if points >= 3000 else "普通")

提醒: 三元只适合简单的二选一,逻辑一复杂就老老实实写回 if-else,可读性要紧。

十、流程控制

if 条件分支

写法 什么时候执行它
if 条件: 条件成立时
elif 条件: 上面全不成立、而这个成立时
else: 所有条件全部落空时
# 两分支
age = 16
if age >= 18:
    print("可以独立办理会员")
else:
    print("需要监护人陪同")

# 多分支:按消费金额给折扣
spending = 1680
if spending >= 2000:
    rate = 0.8
elif spending >= 1000:
    rate = 0.85
elif spending >= 500:
    rate = 0.9
else:
    rate = 1.0
print(f"本次消费享受 {rate} 折")

# 单行版(就是三元表达式)
ship = "免运费" if spending >= 99 else "需付运费"

注意: Python 靠缩进(惯例 4 个空格)划分代码块,没有大括号这回事,缩进就是语法本身。

pass:先占个位

pass 什么都不做,纯粹是个占位符——语法要求这里必须有条语句,但逻辑上暂时还没想好写什么时,就让它顶着。

# 循环体先留空
count = 0
while count < 3:
    pass  # 逻辑以后再补
    count += 1

# 分支先留空
if True:
    pass  # TODO:还没想好怎么写

while 循环

# 基本款:数到 5
num = 1
while num <= 5:
    print(f"第 {num} 杯完成")
    num += 1

# 直到用户喊停
answer = ""
while answer != "stop":
    answer = input("输入 stop 结束:")
    print(f"你输入了:{answer}")

break 与 continue

关键字 效果
break 当场终止整个循环
continue 跳过本轮剩余代码,直接进入下一轮
# break:温度一超标就收工
temp = 20
while temp <= 40:
    if temp > 30:
        print(f"警报:温度达到 {temp} 度")
        break
    temp += 1

# continue:跳过 3 的倍数
num = 0
while num < 12:
    if num % 3 == 0:
        num += 1
        continue
    print(num)  # 1, 2, 4, 5, 7, 8, 10, 11
    num += 1

循环的 else 子句

循环后面可以挂一个 else,当循环自然跑完(中途没被 break 打断)时执行:

# 正常结束,else 就会执行
num = 1
while num <= 3:
    print(num)
    num += 1
else:
    print("循环安然结束")

# 经典场景:找东西
# 在偶数序列 2, 4, 6, ... 里找 7
num = 2
while num <= 10:
    if num == 7:
        print("找到了 7")
        break
    num += 2
else:
    print("没找到 7")  # 会执行这句,因为偶数里没有 7

重要区别: - 循环被 break 打断 → else 不执行 - 循环自然跑完(continue 不算打断)→ else 执行

课后练习

参考答案存放在 ./answers 目录中。

练习一:基础语法输出预测

先不动手运行,逐行读下面的代码,把每个 print 的结果写在注释里,再上机验证。

# 几个变量
stock = 12
price = 45.5
word = "Code"
flag = True
nothing = None

# 1. type 函数
print(type(stock))
print(type(price))
print(type(word))
print(type(flag))
print(type(nothing))
print(type(stock) == int)

# 2. 类型转换
print(int(price))
print(float(stock))
print(str(stock) + word)
print(bool(0))
print(bool(""))
print(bool("ok"))

# 3. 算术运算符
print(stock + 7)
print(stock / 5)
print(stock // 5)
print(stock % 5)
print(stock ** 2)
print(word * 2)

# 4. 字符串格式化(f-string)
book = "数据分析入门"
pages = 320
print(f"书名: {book}, 页数: {pages}")
print(f"第二版增加到{pages + 80}页")
print(f"{stock} + {7} = {stock + 7}")

# 5. 比较运算符与链式比较
print(stock > 8)
print(stock == 12)
print(6 < stock < 20)
print(word == "code")
print("Z" < "a")

# 6. 逻辑运算符
print(True and False)
print(True or False)
print(not flag)
print(0 and 8)
print(7 or 8)
print("" and "ok")
print("ok" or "yes")
print(not None)

# 7. 三元运算符
balance = 650
state = "充足" if balance >= 500 else "不足"
print(state)
grade = "金卡" if balance >= 1000 else ("银卡" if balance >= 600 else "普卡")
print(grade)

# 8. 赋值运算符
y = 8
y += 4
print(y)
y -= 2
print(y)
y *= 3
print(y)
y /= 5
print(y)

t = "第二杯"
t += "半价"
print(t)
t *= 2
print(t)

练习二:循环与分支输出预测

同样先在纸上推演,写出每个 print 的结果,再运行验证。

# 1. while 循环 + if-else
k = 1
total = 0
while k <= 5:
    if k % 2 == 0:
        total -= k
    else:
        total += k
    k += 1
print(total)

# 2. continue 和 break
num = 1
while num <= 10:
    if num == 4:
        num += 1
        continue
    if num == 8:
        break
    print(num)
    num += 1

# 3. 循环 else 子句
j = 0
while j < 3:
    print(j)
    j += 1
else:
    print("over")

# 4. 嵌套条件
y = 25
if y < 20:
    print("A")
elif y < 30:
    if y % 3 == 0:
        print("B")
    else:
        print("C")
else:
    print("D")

# 5. 综合练习
n = 1
acc = 0
while n <= 5:
    if n == 4:
        acc += 12
    elif n % 2 == 0:
        acc += n * 3
    else:
        acc += n
    n += 1
print(acc)

练习三:咖啡因摄入评估器

编写一个评估每日咖啡因摄入的小工具,要求如下:

  1. 用户输入:通过 input() 获取用户的体重(单位:千克)和今天喝的咖啡杯数。

  2. 计算摄入指数:按每杯咖啡约含 80 毫克咖啡因估算,使用公式 摄入指数 = 杯数 × 80 / 体重。

  3. 判断档位: - 指数 < 1.5:较低 - 1.5 ≤ 指数 < 3:适中 - 3 ≤ 指数 < 5:偏高 - 指数 ≥ 5:过量

  4. 输出结果:使用 f-string 格式化输出摄入指数(保留两位小数)和档位结果。

  5. 给出建议:根据档位输出对应建议,例如: - 较低:摄入量不大,正常喝水节奏即可 - 适中:在舒适范围内,注意别太晚喝 - 偏高/过量:建议换成白开水或无因饮品,明显超量时关注身体反应

示例输出:

请输入您的体重(千克):70
请输入您今天喝了几杯咖啡:3
您的咖啡因摄入指数为:3.43
当前档位:偏高
建议:今天的量已经不小,接下来可以换成白开水或无因饮品。

练习四:回文数筛选器

回文数 是指正着读、倒着读都一样的数,例如 11、121、3883;个位数(1~9)天然都是回文数。

编写一个程序,要求如下:

  1. 用户输入:通过 input() 函数获取起始数字和结束数字。

  2. 输入合法性检查: - 输入必须是正整数(大于 0 的整数) - 结束数字必须大于起始数字 - 输入不合法时,给出相应提示并要求重新输入

  3. 回文判断:使用循环逐个判断该范围内的每个数字是否为回文数。

  4. 输出结果:打印该范围内的所有回文数,并统计个数。

示例输出:

请输入起始数字:10
请输入结束数字:60
10 到 60 之间的回文数有:
11 22 33 44 55
共计 5 个回文数

下一章:03 · 序列、字典与集合