基础会了,就能写程序;但 Python 真正的“优雅”在这一章:切片、列表生成式、生成器、函数式编程。它们让你用更少的代码,处理更多的数据——这正是“写得少、做得对”的开始。
nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(nums[0:3]) # 前 3 个 → [0,1,2]
print(nums[-3:]) # 最后 3 个 → [7,8,9]
print(nums[::2]) # 隔一个取 → [0,2,4,6,8]
print(nums[::-1]) # 反转 → [9,8,...,0]
text = "上海自来水来自海上"
print(text == text[::-1]) # 回文?把句子倒过来和原句比
prices = ["¥12", "¥8", "¥20"]
print(prices[1:]) # 从第 2 个开始取一段
path = "data/2024_report_final.csv"
name = path.split("/")[-1]
ext = name[-3:] # 实战:取文件扩展名(后 3 个字符)
print("文件名:", name)
print("扩展名:", ext)
# 凡是能用 for 挨个取出来的,都叫“可迭代”
for ch in "知码": # 字符串可迭代
print(ch)
# dict 默认迭代“键”,想要“键值对”用 .items()
d = {"a": 1, "b": 2}
for k, v in d.items():
print(k, "→", v)
class BookShelf:
def __init__(self, books):
self.books = books
self.i = 0
def __iter__(self):
return self
def __next__(self):
if self.i >= len(self.books):
raise StopIteration
book = self.books[self.i]
self.i += 1
return book
shelf = BookShelf(["三体", "活着", "围城"])
for b in shelf:
print("读:", b)
scores = [88, 92, 75]
for idx, s in enumerate(scores, 1): # 实战:顺便拿到名次
print(f"第{idx}名:{s}分")
squares = [x * x for x in range(1, 6)] # 1~5 的平方
print(squares)
# 带条件的生成式:只要偶数
evens = [x for x in range(10) if x % 2 == 0]
print(evens)
# 把字符串列表全变成大写
words = ["python", "data", "ai"]
upper = [w.upper() for w in words]
print(upper)
celsius = [0, 20, 37]
fahrenheit = [round(c * 9 / 5 + 32, 1) for c in celsius] # 生活:摄氏转华氏
print(fahrenheit)
logs = ["OK 200", "ERR 404", "OK 200", "ERR 500"]
err_codes = [line.split()[1] for line in logs if line.startswith("ERR")] # 实战:从日志揪出错误码
print(err_codes)
def count_up(n):
i = 0
while i < n:
yield i # 每次“暂停”在这里,返回一个值
i += 1
g = count_up(3)
print(next(g)) # 0
print(next(g)) # 1
print(list(count_up(3))) # [0, 1, 2]
def fib():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
f = fib()
for _ in range(6):
print(next(f), end=" ")
print()
import io
fake_file = io.StringIO("hello\n\nworld\n\npython\n") # 模拟一个大文件
def blank_lines(lines): # 实战:逐行扫描,遇到空行才“产出”
for line in lines:
if line.strip() == "":
yield "空行"
blanks = list(blank_lines(fake_file))
print("空行数:", len(blanks))
nums = [1, 2, 3, 4, 5]
doubled = list(map(lambda x: x * 2, nums)) # 每个都乘以 2
print(doubled) # [2,4,6,8,10]
big = list(filter(lambda x: x > 2, nums)) # 只保留 >2 的
print(big) # [3,4,5]
# 其实用列表生成式更直观,二者等价:
print([x * 2 for x in nums])
prices = ["10.5", "3.0", "20.0", "8.5"]
floats = list(map(float, prices)) # 生活:字符串价格 → 数字
print(floats)
cheap = list(filter(lambda p: p < 10, floats)) # 只要便宜的
print(cheap)
students = [("小明", 88), ("小红", 95), ("小刚", 72)]
ranked = sorted(students, key=lambda s: s[1], reverse=True) # 实战:按成绩排名
print(ranked)
from functools import wraps
def log_calls(func): # 装饰器:接收原函数
@wraps(func) # 保住原函数的名字、文档
def wrapper(*args, **kw):
print(f"调用 {func.__name__},参数 {args} {kw}")
return func(*args, **kw)
return wrapper
@log_calls # 用 @ 把装饰器“贴”在函数上
def add(a, b):
return a + b
print(add(3, 4))
def retry(times):
def deco(func):
def wrapper(*args, **kw):
for i in range(times):
try:
return func(*args, **kw)
except Exception:
print(f"第{i+1}次失败,重试…")
return None
return wrapper
return deco
@retry(2)
def unstable():
raise ValueError("网络抖了一下")
print(unstable())
cache = {}
def memo(func):
def wrapper(n):
if n in cache:
return cache[n]
cache[n] = func(n)
return cache[n]
return wrapper
@memo
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
print(fib(10)) # 第 11 个斐波那契数
import functools
def tag(func):
@functools.wraps(func) # 保住原函数元信息
def wrapper():
return func()
return wrapper
@tag
def hello():
return "hi"
print(hello.__name__) # hello(不再是 wrapper)
假设有一批带空格和大小写混乱的文件名,用一行生成式把它们统一成“小写、去空格、下划线连接”。
raw = [" My Photo.JPG", "Report Final.pdf", "DATA_2024.csv"]
clean = ["_".join(name.strip().lower().split()) for name in raw]
print(clean) # ['my_photo.jpg', 'report_final.pdf', 'data_2024.csv']
1用切片把字符串 "Hello, Python" 反转,并取出最后 6 个字符(应为 "Python")。
2用列表生成式生成 1~10 中所有的偶数平方,结果应为 [4, 16, 36, 64, 100]。
提示:切片 [::-1] 反转;生成式里用 if x % 2 == 0 筛选,再算平方。
s = "Hello, Python"
print(s[::-1]) # 反转
print(s[-6:]) # 最后 6 个字符
evens_sq = [x * x for x in range(1, 11) if x % 2 == 0]
print(evens_sq)