Appearance
数据结构
前面用的变量一次只存一个值。真要处理"一批待办""一组联系人""一篇文章的多个标签",就得用列表、字典、元组、集合这些数据结构。选对结构,后面的循环、查找、统计都会顺;选错了,代码绕来绕去还容易出错。
打个比方:变量是一个格子,列表是一排格子(有顺序),字典是带标签的格子(按名字取),集合是一堆不重复的东西,元组是封死的格子(不能改)。这四种各有各的用处。
一、列表
列表是有顺序的集合,用方括号 []。适合保存一组同类的东西——一批待办、一组名字、几个文件路径:
python
todos = ["写周报", "回邮件", "开会"]
# 增删改查
todos.append("写文档") # 末尾追加
todos.insert(0, "紧急任务") # 在指定位置插入
todos.remove("回邮件") # 按值删除(只删第一个匹配的)
print(todos[0]) # 取第一个:紧急任务
print(todos[-1]) # 取最后一个:写文档
todos[1] = "改完周报" # 修改指定位置负数下标是 Python 的好用之处:-1 是最后一个,-2 是倒数第二个,不用先算长度。
切片——取出一段连续的元素:
python
todos = ["a", "b", "c", "d", "e"]
print(todos[0:3]) # ['a', 'b', 'c'] 第 0 到第 2 个(不含第 3)
print(todos[2:]) # ['c', 'd', 'e'] 从第 2 个到末尾
print(todos[:2]) # ['a', 'b'] 从开头到第 1 个切片的规则是"左闭右开":todos[0:3] 包含 0、1、2,不包含 3。一开始容易记混,多写几次就习惯了。
判断元素在不在列表里,用 in:
python
if "开会" in todos:
print("还有会要开")但要注意:在列表里查"有没有某个元素"是逐个比对,列表越长越慢。如果要频繁判断大量元素是否存在,集合在这种场景比列表快得多。
二、字典
字典是 key-value 结构,用花括号 {}。适合保存"每个对象都有一组属性"的场景——一个联系人有名字/电话/邮箱,一篇文章有标题/作者/字数:
python
contact = {
"name": "张三",
"phone": "13800000001",
"email": "zhangsan@example.com",
}
print(contact["name"]) # 按 key 取值:张三
contact["phone"] = "13900000001" # 修改值
contact["note"] = "重要客户" # 新增一个 key直接用 contact["xxx"] 取值,key 不存在会报 KeyError 直接崩。更安全的写法是 get:
python
print(contact.get("fax")) # key 不存在,返回 None(不报错)
print(contact.get("fax", "未填写")) # key 不存在,返回默认值"未填写"get 在处理"不确定有没有的字段"时特别有用,比如解析外部数据,有些字段可能缺失。
遍历字典:
python
for key, value in contact.items():
print(f"{key}: {value}")只想要 key,写 for key in contact:;想要 key 和 value,写 for key, value in contact.items():。items() 别忘了加,这是新手常漏的。
嵌套字典很常见——一组联系人,每个又是一个字典:
python
contacts = {
"张三": {"phone": "13800000001", "city": "北京"},
"李四": {"phone": "13800000002", "city": "上海"},
}
for name, info in contacts.items():
print(f"{name} 在 {info['city']},电话 {info['phone']}")访问嵌套字段时要小心:contacts["张三"]["phone"],如果"张三"不存在,或者里面的结构少了一层,就会报错。处理外部数据时,稳妥的写法是一层一层用 get。
三、元组
元组是不可变的列表,用圆括号 ()。创建之后不能改——不能增删改元素:
python
point = (3, 5) # 一个坐标
rgb = (255, 128, 0) # 一个颜色既然不能改,为什么还要它?有两个常见用途:
第一,表示"固定的一组值"。坐标的两个数、RGB 的三个数,语义上就是绑定的,不该单独改其中一个。用元组能防止误改。
第二,函数返回多个值。Python 函数可以一次返回多个值,本质就是返回一个元组:
python
def get_dimensions():
width = 100
height = 60
return width, height # 返回的是元组 (100, 60)
w, h = get_dimensions() # 拆开接收
print(w, h) # 100 60这种"一次返回多个值,接收时拆开"的写法在 Python 里特别常见,比用一个列表或字典包起来简洁。
四、集合
集合是不重复元素的集合,用 set() 或花括号 {}(里面放值)。最大的特点是:自动去重,而且查"在不在"特别快:
python
tags = ["工作", "工作", "重要", "本周", "重要"]
unique_tags = set(tags)
print(unique_tags) # {'工作', '重要', '本周'} 自动去重
print("工作" in unique_tags) # True,判断很快集合没有顺序(遍历的顺序不固定),需要排序时再排:
python
for tag in sorted(unique_tags):
print(tag)集合还能做集合运算——交集、并集、差集:
python
todo_tags = {"工作", "重要", "本周"}
done_tags = {"工作", "本周"}
print(todo_tags & done_tags) # 交集:两个都有的 {'工作', '本周'}
print(todo_tags - done_tags) # 差集:todo 有 done 没有的 {'重要'}
print(todo_tags | done_tags) # 并集:合起来去重 {'工作', '重要', '本周'}集合运算在"找出两批数据的差异"时很好用——比如"这周该做的标签里,哪些还没做完",就是差集。
五、四种结构怎么选
| 结构 | 特点 | 典型场景 |
|---|---|---|
列表 [] | 有顺序、可改、可重复 | 一批同类项:待办列表、文件路径 |
字典 {} | key-value、按 key 取值 | 对象属性、配置、映射关系 |
元组 () | 不可变 | 固定一组值、函数多返回值 |
集合 set | 不重复、查得快、集合运算 | 去重、成员判断、找差异 |
最常见的误用:该用字典的地方用了两个列表(一个存 key、一个存 value,然后靠下标对应)。这种写法一旦两边长度对不上就出错,直接用字典干净得多。