03.学了 Python 三个月还在手写循环?列表推导式一行搞定的事你写十行
·
学了 Python 三个月还在手写循环?列表推导式一行搞定的事你写十行
前几天帮朋友 review 代码,看到这么一段:
result = []
for i in range(10):
if i % 2 == 0:
result.append(i * i)
我问他:你知道这五行代码一行就能写完吗?
他一脸震惊。
今天聊 Python 里最常用的两个数据结构——列表和字典。不只是基础操作,还有那些让你代码"看起来会 Python"的写法。
列表:最灵活的容器
列表就是用方括号 [] 包起来的一串数据,可以放任何类型:
fruits = ["苹果", "香蕉", "橘子"]
mixed = [1, "hello", 3.14, True, [1, 2, 3]] # 还能嵌套列表
empty = [] # 空列表
增删改查四件套
nums = [1, 2, 3]
# 增
nums.append(4) # 末尾加一个 → [1, 2, 3, 4]
nums.insert(1, 99) # 在位置1插入99 → [1, 99, 2, 3, 4]
nums.extend([5, 6]) # 合并另一个列表 → [1, 99, 2, 3, 4, 5, 6]
# 删
nums.pop() # 删除最后一个,返回6
nums.pop(1) # 删除位置1的元素(99)
nums.remove(3) # 删除第一个值为3的元素
del nums[0] # 直接删位置0
# 改
nums[0] = 100 # 位置0改成100
# 查
print(nums[0]) # 查位置0
print(nums[-1]) # 查最后一个,负数从末尾倒着数
print(nums[1:3]) # 切片:位置1到3(不含3)
print(5 in nums) # 判断5在不在列表里 → True/False
遍历列表
# 基础遍历
for fruit in fruits:
print(fruit)
# 需要索引时用 enumerate
for i, fruit in enumerate(fruits):
print(f"{i}: {fruit}")
# 同时遍历两个列表用 zip
names = ["张三", "李四", "王五"]
scores = [85, 92, 78]
for name, score in zip(names, scores):
print(f"{name}考了{score}分")
列表推导式:Python 的灵魂
一句话:把 for 循环压成一行。
# 需求:生成 0-9 的平方数列表
# 传统写法
squares = []
for i in range(10):
squares.append(i * i)
# 列表推导式
squares = [i * i for i in range(10)]
# 加条件过滤:只要偶数的平方
even_squares = [i * i for i in range(10) if i % 2 == 0]
# 还能嵌套
matrix = [[i * j for j in range(1, 4)] for i in range(1, 4)]
# [[1, 2, 3], [2, 4, 6], [3, 6, 9]]
刚接触可能觉得有点绕,多用几次就离不开了。代码量直接砍半,可读性反而更高。
字典:万物皆可键值对
# 花括号创建
user = {
"name": "张三",
"age": 28,
"city": "北京"
}
# dict() 创建
user2 = dict(name="李四", age=25, city="上海")
# 空字典
empty = {}
字典的基本操作
# 取值
print(user["name"]) # "张三"
print(user.get("phone")) # None(键不存在也不报错)
print(user.get("phone", "无")) # "无"(不存在时返回默认值)
# 增/改
user["email"] = "zhangsan@example.com" # 新增
user["age"] = 29 # 修改
# 删
del user["city"]
email = user.pop("email") # 删除并返回值
# 遍历
for key in user: # 遍历键
print(key)
for value in user.values(): # 遍历值
print(value)
for key, value in user.items(): # 遍历键值对(最常用)
print(f"{key}: {value}")
get() 比 [] 安全在哪
# ❌ 键不存在直接报错
print(user["phone"]) # KeyError: 'phone'
# ✅ 键不存在返回 None,程序继续跑
print(user.get("phone")) # None
print(user.get("phone", "未填写")) # "未填写"
用 get() 能避免一半以上的字典相关 bug。养成习惯。
字典推导式
# 把列表转成字典:名字→长度
words = ["apple", "banana", "cherry"]
word_len = {w: len(w) for w in words}
# {'apple': 5, 'banana': 6, 'cherry': 6}
# 条件过滤
long_words = {k: v for k, v in word_len.items() if v > 5}
# {'banana': 6, 'cherry': 6}
什么时候用列表,什么时候用字典?
用列表: 数据有顺序、需要遍历、需要索引访问
- 学生名单、待办事项、一堆数字
用字典: 需要通过"名字"快速找到"值"、键值一一对应
- 用户信息、配置项、统计计数
一个小经验:如果你经常写 for item in data,然后 if item["id"] == target_id 这种代码,说明你应该用字典而不是列表。
实战:做个简单通讯录
contacts = {} # 名字 → 电话
def add_contact(name, phone):
contacts[name] = phone
print(f"已添加:{name}")
def find_contact(name):
phone = contacts.get(name)
if phone:
print(f"{name} 的电话:{phone}")
else:
print(f"未找到 {name}")
def list_contacts():
if not contacts:
print("通讯录为空")
return
for name, phone in contacts.items():
print(f"{name}: {phone}")
# 试试
add_contact("张三", "13800138000")
add_contact("李四", "13900139000")
find_contact("张三")
list_contacts()
三个新手常掉的坑
坑 1:列表复制不彻底
a = [1, 2, 3]
b = a # ⚠️ b 和 a 指向同一个列表
b.append(4)
print(a) # [1, 2, 3, 4] ← a 也被改了!
b = a.copy() # ✅ 浅拷贝
b = a[:] # ✅ 也是浅拷贝
b = list(a) # ✅ 也能拷贝
坑 2:遍历列表时删除元素
nums = [1, 2, 3, 4, 5]
for n in nums:
if n % 2 == 0:
nums.remove(n) # ❌ 遍历时删元素,结果不可预测
# ✅ 创建新列表
nums = [n for n in nums if n % 2 != 0]
坑 3:字典的键必须不可变
# ❌ 列表是可变类型,不能当键
# d = {[1, 2]: "value"} # TypeError
# ✅ 字符串、数字、元组都可以
d = {(1, 2): "value"}
d = {"name": "张三"}
d = {1: "one"}
动手试试
- 用列表推导式生成 1-100 中所有能被 3 或 5 整除的数
- 统计一句话中每个单词出现的次数(用字典)
- 把一个列表去重(提示:转成集合再转回来)
参考答案:
# 1. 列表推导式
nums = [i for i in range(1, 101) if i % 3 == 0 or i % 5 == 0]
# 2. 单词计数
sentence = "the quick brown fox jumps over the lazy dog"
words = sentence.split()
word_count = {}
for word in words:
word_count[word] = word_count.get(word, 0) + 1
print(word_count)
# 3. 去重
lst = [1, 2, 2, 3, 3, 3, 4]
unique = list(set(lst))
print(unique) # [1, 2, 3, 4]
写在最后
列表和字典是你写 Python 时碰得最多的东西。把推导式练熟、把 get() 养成肌肉记忆,你的代码水平会有肉眼可见的提升。
还是那句话:不是语法学会了就叫"会用"。当你开始下意识地选最合适的数据结构,而不是所有场景都用列表硬刚,才算真的入门了。
下一篇聊函数——终于可以把重复代码揪出来、打包、只用改一个地方了。
更多推荐
所有评论(0)