序列、字典与集合
前面学过的变量,一次只能攥住一个值。可现实里的数据很少这么"独来独往":一张订单挂着好几件商品,一张名片挤着姓名、电话、职位好几个字段,一个商品可能贴着一堆标签。Python 为这类"批量数据"准备了一整套内置的打包工具…
一个变量,装下一组数据
前面学过的变量,一次只能攥住一个值。可现实里的数据很少这么"独来独往":一张订单挂着好几件商品,一张名片挤着姓名、电话、职位好几个字段,一个商品可能贴着一堆标签。Python 为这类"批量数据"准备了一整套内置的打包工具,统称容器。
先来一张全家福:
| 类型 | 俗称 | 能否原地修改 | 是否有序 | 元素可否重复 | 示例 |
|---|---|---|---|---|---|
list |
列表 | 能 | 有序 | 可重复 | [1, 2, 2, 3] |
tuple |
元组 | 不能 | 有序 | 可重复 | (1, 2, 3) |
dict |
字典 | 能 | 有序(3.7 版本起保证) | 键不可重复 | {"a": 1, "b": 2} |
set |
集合 | 能 | 无序 | 不可重复 | {1, 2, 3} |
str |
字符串 | 不能 | 有序 | 可重复 | "hello" |
顺带说一句:字符串其实也可以当成"一串排好队的字符"来用,本章的不少操作对它照样有效,讲解过程中会穿插演示。
列表:随改随用的活页本
列表大概是日后出场率最高的容器——它有顺序、能随时往里加东西、删东西、改东西,装什么类型的元素都行。
怎么造一个列表
# 直接写出字面量
orders = [301, 302, 303, 304, 305]
mixed_bag = [42, "少冰", 3.5, True, None]
blank = [] # 空列表,先备着,回头往里装
# 用 list() 从别的数据转换而来
letters = list("abc") # ['a', 'b', 'c']
from_tuple = list((7, 8, 9)) # [7, 8, 9]
按位置取值:索引与切片
menu = ["美式", "拿铁", "卡布奇诺", "摩卡", "冷萃"]
# 索引从 0 开始数
print(menu[0]) # 美式
print(menu[-1]) # 冷萃(负数表示从队尾倒着数)
# 切片格式 [起点:终点:步长],特点是"包头不包尾"
print(menu[1:4]) # ['拿铁', '卡布奇诺', '摩卡'] —— 落在区间 [1, 4) 内的元素
print(menu[:3]) # ['美式', '拿铁', '卡布奇诺'] —— 起点不写就从头开始
print(menu[2:]) # ['卡布奇诺', '摩卡', '冷萃'] —— 终点不写就取到队尾
print(menu[::2]) # ['美式', '卡布奇诺', '冷萃'] —— 步长 2,隔一个取一个
print(menu[1:4:2]) # ['拿铁', '摩卡'] —— 区间 [1, 4),步长 2
print(menu[::-1]) # ['冷萃', '摩卡', '卡布奇诺', '拿铁', '美式'] —— 步长为负,整串倒着走
增删改查一把抓
queue = [11, 22, 33]
# 往里加
queue.append(44) # [11, 22, 33, 44] 追加到队尾
queue.insert(0, 5) # [5, 11, 22, 33, 44] 插队到指定位置
queue.extend([55, 66]) # [5, 11, 22, 33, 44, 55, 66] 把另一份列表整个接上来
# 往外删
queue.remove(5) # [11, 22, 33, 44, 55, 66] 按值删,只删碰到的第一个
tail = queue.pop() # 66,队列变为 [11, 22, 33, 44, 55] 弹出队尾并返回
head = queue.pop(0) # 11,队列变为 [22, 33, 44, 55] 弹出指定位置并返回
del queue[0] # [33, 44, 55] 按位置删
queue.clear() # [] 一键清空
# 查位置、数次数
votes = [10, 20, 30, 20, 40]
print(votes.index(20)) # 1 第一次出现的位置
print(votes.count(20)) # 2 总共出现了几回
# 排序与翻转(会直接改动原列表)
fares = [23, 8, 42, 8, 15]
fares.sort() # [8, 8, 15, 23, 42] 从小到大,原地排
fares.sort(reverse=True) # [42, 23, 15, 8, 8] 从大到小
fares.reverse() # [8, 8, 15, 23, 42] 原地翻转
# 想保留原始顺序?改用 sorted(),它返回新列表
fares = [23, 8, 42]
ordered = sorted(fares) # [8, 23, 42],fares 本身原封不动
# 修改指定位置
fares[0] = 99 # [99, 8, 42]
# fares[3] = 1 # IndexError: list assignment index out of range
元组:一次定稿、终身只读
元组像是"塑封"过的列表:内容一旦写好就不许再动。适合存放那些不该被意外修改的数据,比如坐标、配置项。
怎么造一个元组
# 字面量写法,圆括号可以偷懒不写
pixel = (120, 200, 60)
pixel = 120, 200, 60 # 和上面完全等价
single = (9,) # 只有一个元素时,逗号不能省!写成 (9) 只是个普通数字
empty = () # 空元组
# 用 tuple() 转换
t = tuple([4, 5, 6]) # (4, 5, 6)
t = tuple("hi") # ('h', 'i')
能做什么、不能做什么
t = (6, 3, 9, 3, 12)
# 索引和切片,玩法与列表完全一致
print(t[0]) # 6
print(t[-1]) # 12
print(t[1:4]) # (3, 9, 3)
# 查询没问题
print(t.index(3)) # 1
print(t.count(3)) # 2
print(9 in t) # True
# 但改动是禁区
# t[0] = 66 # TypeError: 'tuple' object does not support item assignment
# t.append(7) # AttributeError
解包:一口气把值分给多个变量
# 基础解包
rgb = (52, 96, 235)
r, g, b = rgb
print(r, g, b) # 52 96 235
# 星号解包:剩下的统统归它
head, *tail = (1, 2, 3, 4)
print(head) # 1
print(tail) # [2, 3, 4]
*front, tail = (1, 2, 3, 4)
print(front) # [1, 2, 3]
print(tail) # 4
# 交换两个变量的经典写法
left, right = "前", "后"
left, right = right, left # 现在 left="后",right="前"
字典:拿"名字"去查数据的登记簿
字典不靠位置找数据,而是靠键(key)直达对应的值(value),查起来非常快。
怎么造一个字典
# 字面量写法
book = {
"title": "三体",
"author": "刘慈欣",
"year": 2008
}
empty = {} # 空字典
# 用 dict() 创建
book = dict(title="球状闪电", author="刘慈欣", year=2004)
book = dict([("title", "三体"), ("year", 2008)])
# 拿一串键批量开空档,值先统一填充
shifts = dict.fromkeys(["早班", "中班", "晚班"], 0)
# {'早班': 0, '中班': 0, '晚班': 0}
读与写
book = {"title": "三体", "author": "刘慈欣"}
# 读取:方括号直取
print(book["title"]) # 三体
# print(book["price"]) # KeyError!键不存在就直接翻脸
# 稳妥的读法:get,查不到也不炸
print(book.get("price")) # None(不传默认值时)
print(book.get("price", "未登记")) # 未登记(给个兜底值)
# 新增 / 修改
book["price"] = 45.5 # 原来没有这个键 → 新增
book["year"] = 2008 # 已有这个键 → 覆盖旧值
# 批量写入
book.update({"publisher": "重庆出版社", "year": 2008})
# 删除
del book["publisher"] # 按键删
value = book.pop("price") # 删掉并顺手把值拿回来
last_item = book.popitem() # 弹出最后写进来的那对键值(3.7 版本起)
book.clear() # 清空
两条铁律
# 铁律一:键必须是不可变(可哈希)的类型
workable = {
"level": 3, # str ✓
1024: "内存", # int ✓
(2, 5): "坐标", # tuple ✓
# [1, 2]: " Nope", # list ✗ 列表可变,没法当键!
}
# 铁律二:键天然去重,后来者覆盖先行者
floor = {"楼层": 1, "楼层": 3}
print(floor) # {'楼层': 3}
集合:自动去重的百宝袋
集合有两大人设:元素不重复、不讲究顺序。它还是做数学集合运算的一把好手。
怎么造一个集合
# 字面量写法,重复的元素会被自动吞掉
labels = {"新品", "热销", "新品", "热销"} # {'新品', '热销'}
empty = set() # 注意:空集合必须用 set(),写成 {} 造出来的是空字典!
# 用 set() 转换
nums = set([1, 2, 2, 3]) # {1, 2, 3}
chars = set("moon") # {'m', 'o', 'n'}
集合的日常操作
s = {1, 2, 3}
# 添加与删除
s.add(4) # {1, 2, 3, 4}
s.remove(2) # {1, 3, 4} —— 要删的元素不存在会抛 KeyError
s.discard(10) # 删不存在的元素也一声不吭,不报错
s.pop() # 随机弹出一个元素并返回(谁先谁后说不准)
s.clear() # set()
# 去重是集合的主场
orders = [501, 502, 501, 503, 502, 502]
unique = list(set(orders)) # [501, 502, 503](顺序不保证)
五类容器通吃的工具函数
下面这批内置函数,list、tuple、dict、set、str 全部适用:
# len() —— 数一数有多少个元素
len([1, 2, 3]) # 3
len((7, 8, 9)) # 3
len({"冷萃": 12, "拿铁": 8}) # 2(按键值对计数)
len("cake") # 4
# max() / min() —— 挑最大、挑最小
max([23, 8, 42, 15]) # 42
min((6, 1, 8)) # 1
max("cake") # 'k'(按字符编码比较)
# sum() —— 求和(元素得是数字)
sum([2, 4, 6, 8]) # 20
sum((1, 2, 3)) # 6
# sorted() —— 排序,一律返回新列表
sorted([3, 1, 2]) # [1, 2, 3]
sorted((9, 5, 7)) # [5, 7, 9] —— 元组进来,列表出去
sorted("onion") # ['i', 'n', 'n', 'o', 'o']
sorted([3, 1, 2], reverse=True) # [3, 2, 1]
# reversed() —— 反转,返回的是迭代器,套一层 list() 再看
list(reversed([1, 2, 3])) # [3, 2, 1]
list(reversed("abc")) # ['c', 'b', 'a']
容器身边的运算符
判断"在不在":in / not in
# 列表
42 in [23, 42, 8] # True
9 not in [23, 42, 8] # True
# 元组
"春" in ("春", "夏", "秋") # True
# 字符串 —— 查的是子串
"ca" in "cake" # True
"z" not in "cake" # True
# 字典 —— 查的是键,跟值没关系
"冷萃" in {"冷萃": 12, "拿铁": 8} # True
12 in {"冷萃": 12, "拿铁": 8} # False
# 集合
2 in {1, 2, 3} # True
拼接与复制:+ 与 *
# + 拼接(只有有序容器支持)
[1, 2] + [3, 4] # [1, 2, 3, 4]
(1, 2) + (3, 4) # (1, 2, 3, 4)
"hot" + "dog" # "hotdog"
# {1, 2} + {3, 4} # TypeError!集合不吃这一套
# * 复制(同样只限有序容器)
[0, 1] * 3 # [0, 1, 0, 1, 0, 1]
"~" * 8 # "~~~~~~~~"
比内容:== / !=
== 关心的是两个容器装的东西是否一样,而不是它们是不是同一个对象。
判定的四步逻辑:
- 类型先对上:类型不同,哪怕内容看着一样也不算相等,
[1, 2] == (1, 2)是False。 - 长度得一样:长度对不上,直接判不等。
- 逐个位置比:从第 0 位开始一对一对地比;碰到嵌套容器,会一层层递归往里比。
- 元素自己说了算:容器不掺和元素怎么算相等,而是调用元素自己的比较逻辑,所以
[1, 2] == [1.0, 2.0]是True。
# 基本比较
[2, 4, 6] == [2, 4, 6] # True,内容一致
[2, 4, 6] == [6, 4, 2] # False,顺序也是内容的一部分
# 类型不同
[1, 2] == (1, 2) # False
# 嵌套结构递归比较
[[1, 2], [3]] == [[1, 2], [3]] # True
# 字典只看键值对是否一致
{"a": 1, "b": 2} == {"b": 2, "a": 1} # True,书写顺序不影响
提醒:
==判断的是值相等,不是身份相同(内存里是不是同一个对象)。想知道身份,得用下面的is。
比身份:is / is not
is 回答的问题是:两个变量是不是指着内存里同一个对象?等价于比较它们的 id()。
a = [1, 2, 3]
b = a # b 和 a 指向同一个列表
c = [1, 2, 3] # c 另起炉灶,新建了一个列表
a is b # True,确实是同一个对象
a is c # False,内容虽同,对象是两个
a == c # True,光看内容是相等的
a is not c # True
高频使用场景:
# 判断是否为 None —— 官方推荐写法
value = None
if value is None:
print("空值")
# 判断单例对象
flag = True
flag is True # True
# 小整数缓存:解释器的优化手段
a = 100
b = 100
a is b # True(-5 到 256 范围内的整数会被缓存共用)
x = 1000
y = 1000
x is y # False(通常如此,具体取决于解释器实现)
一句话分清: -
==问"你们俩长得一样吗?"(比值) -is问"你们俩是同一个人吗?"(比身份) - 跟None比较时,永远用is,别用==
集合专属:&、|、-、^
这四个位运算符放在集合身上,含义摇身一变成了集合运算:
vip_old = {101, 102, 103}
vip_new = {102, 103, 104}
# & 交集 —— 两边都有的
vip_old & vip_new # {102, 103}
# | 并集 —— 两边合起来,自动去重
vip_old | vip_new # {101, 102, 103, 104}
# - 差集 —— 我有而你没有的
vip_old - vip_new # {101}
vip_new - vip_old # {104}
# ^ 对称差集 —— 只属于其中一边的
vip_old ^ vip_new # {101, 104}
# ~ 是整数按位取反用的,跟集合没关系
两种写法对照:运算符 vs 方法名
vip_old = {101, 102, 103}
vip_new = {102, 103, 104}
# 运算符风格
vip_old & vip_new # {102, 103}
vip_old | vip_new # {101, 102, 103, 104}
vip_old - vip_new # {101}
vip_old ^ vip_new # {101, 104}
# 方法风格(效果一样)
vip_old.intersection(vip_new) # {102, 103}
vip_old.union(vip_new) # {101, 102, 103, 104}
vip_old.difference(vip_new) # {101}
vip_old.symmetric_difference(vip_new) # {101, 104}
注意:这四个符号只对集合(set)生效,套在
list、tuple、dict上会直接报错。
遍历容器的几种姿势
最朴素的 for
# 列表
for item in [10, 20, 30]:
print(item)
# 元组
for season in ("春", "夏", "秋"):
print(season)
# 字符串
for ch in "tea":
print(ch) # t, e, a
字典的三种遍历角度
cafe = {"冷萃": 18, "拿铁": 22, "抹茶": 25}
# 默认拿到的是键
for name in cafe:
print(name)
# 键值成对拿
for name, price in cafe.items():
print(name, price)
# 只看值
for price in cafe.values():
print(price)
# 只看键(写明白一点)
for name in cafe.keys():
print(name)
集合也能遍历,但别指望顺序
tags = {"科幻", "悬疑", "剧情"}
for tag in tags:
print(tag)
# 集合内部无序,每次遍历输出的先后不一定相同
enumerate():序号和数据一起发
光遍历不够,还想知道"这是第几个",就请 enumerate() 出场:
steps = ["取号", "等待", "办理"]
# 基本用法
for index, step in enumerate(steps):
print(f"{index}: {step}")
# 0: 取号
# 1: 等待
# 2: 办理
# 让编号从 1 开始
for no, step in enumerate(steps, start=1):
print(f"{no}. {step}")
# 1. 取号
# 2. 等待
# 3. 办理
zip():多条队伍并排走
把多个容器按位置两两配对,同步遍历:
lines = ["1号线", "2号线", "3号线"]
loads = [850, 620, 730]
for line, load in zip(lines, loads):
print(f"{line}今日客流 {load} 万人次")
# zip 以最短的那条为准,长了的部分直接舍弃
short = [10, 20]
long = ["a", "b", "c"]
for x, y in zip(short, long):
print(x, y)
# 只会输出两组:10 a 和 20 b
练习
练习一:副本与本尊(列表 + 身份运算符)
逐行阅读下面的代码,先在纸上写出每个 print 的输出,再运行验证。
points = [6, 1, 8, 1, 4]
mirror = points[:]
print(points == mirror, points is mirror)
points[0] = 10
print(points[0], mirror[0])
print(points == mirror, points is mirror)
print(len(points))
i = 0
hits = 0
while i < len(points):
if points[i] > 3:
hits += 1
i += 1
print(hits)
练习二:元组、集合与成员判断
逐行阅读下面的代码,先在纸上写出每个 print 的输出,再运行验证。
t = (4, 7, 1, 7)
head, *tail = t
print(head, tail)
print(sorted(t))
print(7 in t, 3 not in t)
s = set(t)
print(len(s))
s2 = {7, 1, 9}
print(s & s2, s | s2)
练习三:字典的增删与遍历
逐行阅读下面的代码,先在纸上写出每个 print 的输出,再运行验证。
menu = {"面条": 12, "米饭": 22}
menu["饺子"] = 30
menu.update({"面条": 15})
print(len(menu))
print("面条" in menu, 22 in menu)
print(menu.get("汉堡", 0))
keys = []
for k in menu:
keys.append(k)
print(keys)
i = 0
while i < len(keys):
k = keys[i]
if menu[k] > 15:
print(k)
i += 1
练习四:字符串与循环
逐行阅读下面的代码,先在纸上写出每个 print 的输出,再运行验证。
word = "banana"
print(word[1:4])
print("na" in word, "q" not in word)
print(word + " juice", word * 2)
i = 0
vowels = "aeiou"
count = 0
while i < len(word):
if word[i] in vowels:
count += 1
i += 1
print(count)
print(f"length: {len(word)}")
练习五:zip 与 enumerate 联合作业
逐行阅读下面的代码,先在纸上写出每个 print 的输出,再运行验证。
dishes = ["宫保鸡丁", "麻婆豆腐"]
prices = (38, 26)
pairs = []
for dish, price in zip(dishes, prices):
pairs.append(f"{dish}-{price}")
print(pairs)
for no, dish in enumerate(dishes, 1):
print(no, dish)
d = {}
i = 0
while i < len(dishes):
if prices[i] > 20:
d[dishes[i]] = prices[i]
i += 1
print(len(d))
print(d.get("宫保鸡丁"))
print(d.get("回锅肉", "今日无货"))
练习六:员工档案综合实战
下面是一份员工信息列表,请按任务要求逐一编写代码。
要求: 全部任务只用循环和条件判断实现,先不要使用列表推导式。
staff = [
{"id": 100237, "name": "周建军", "sex": "男", "age": 35, "city": "四川省 成都市", "phone": "13801234567"},
{"id": 205481, "name": "吴丽华", "sex": "女", "age": 28, "city": "浙江省 杭州市", "phone": "15923456789"},
{"id": 309712, "name": "孙志强", "sex": "男", "age": 42, "city": "山东省 济南市", "phone": "18634567890"},
{"id": 415836, "name": "李雪梅", "sex": "女", "age": 31, "city": "江苏省 南京市", "phone": "17745678901"},
{"id": 520318, "name": "陈国栋", "sex": "男", "age": 38, "city": "广东省 广州市", "phone": "13556789012"},
{"id": 601942, "name": "王秀兰", "sex": "女", "age": 44, "city": "河南省 郑州市", "phone": "15867890123"},
{"id": 714728, "name": "周敏", "sex": "女", "age": 26, "city": "湖北省 武汉市", "phone": "13678901234"},
{"id": 826503, "name": "郑涛", "sex": "男", "age": 29, "city": "福建省 福州市", "phone": "18890123456"},
{"id": 937215, "name": "何静", "sex": "女", "age": 33, "city": "湖南省 长沙市", "phone": "15601237893"},
{"id": 104836, "name": "罗建国", "sex": "男", "age": 45, "city": "陕西省 西安市", "phone": "13912345678"},
{"id": 215940, "name": "高芳", "sex": "女", "age": 24, "city": "四川省 绵阳市", "phone": "15023456781"},
{"id": 327164, "name": "林伟", "sex": "男", "age": 36, "city": "安徽省 合肥市", "phone": "18734567892"},
{"id": 438579, "name": "黄丽", "sex": "女", "age": 27, "city": "江西省 南昌市", "phone": "13645678933"},
{"id": 541690, "name": "张勇", "sex": "男", "age": 41, "city": "辽宁省 沈阳市", "phone": "15956789012"},
{"id": 652873, "name": "徐桂英", "sex": "女", "age": 43, "city": "黑龙江省 哈尔滨市", "phone": "13867890123"},
{"id": 763915, "name": "周涛", "sex": "男", "age": 30, "city": "河北省 石家庄市", "phone": "18678901273"},
{"id": 874620, "name": "谢婷", "sex": "女", "age": 22, "city": "云南省 昆明市", "phone": "15789012346"},
{"id": 985134, "name": "马超", "sex": "男", "age": 34, "city": "贵州省 贵阳市", "phone": "13501234568"},
{"id": 109257, "name": "唐秀英", "sex": "女", "age": 39, "city": "广西壮族自治区 南宁市", "phone": "15812345673"},
{"id": 210348, "name": "冯军", "sex": "男", "age": 25, "city": "山西省 太原市", "phone": "18623456789"},
{"id": 321569, "name": "曹丽华", "sex": "女", "age": 37, "city": "吉林省 长春市", "phone": "13734567890"},
{"id": 432680, "name": "邓强", "sex": "男", "age": 28, "city": "重庆市 重庆市", "phone": "15945678901"},
{"id": 543791, "name": "萧芳", "sex": "女", "age": 26, "city": "甘肃省 兰州市", "phone": "15856789023"},
{"id": 654802, "name": "董伟", "sex": "男", "age": 33, "city": "青海省 西宁市", "phone": "13567890124"},
{"id": 765913, "name": "程娜", "sex": "女", "age": 29, "city": "海南省 海口市", "phone": "18678901235"},
{"id": 876024, "name": "宋磊", "sex": "男", "age": 36, "city": "内蒙古自治区 呼和浩特市", "phone": "17890123456"},
{"id": 987135, "name": "石秀珍", "sex": "女", "age": 41, "city": "新疆维吾尔自治区 乌鲁木齐市", "phone": "13690123457"},
{"id": 108246, "name": "姚刚", "sex": "男", "age": 27, "city": "宁夏回族自治区 银川市", "phone": "18901234563"},
{"id": 219357, "name": "潘淑华", "sex": "女", "age": 34, "city": "西藏自治区 拉萨市", "phone": "15112345670"},
{"id": 320468, "name": "江海", "sex": "男", "age": 39, "city": "天津市 天津市", "phone": "13623456788"},
{"id": 431579, "name": "段鹏", "sex": "男", "age": 32, "city": "北京市 北京市", "phone": "15834567891"},
{"id": 542680, "name": "贺晓燕", "sex": "女", "age": 23, "city": "上海市 上海市", "phone": "18745678902"},
{"id": 653791, "name": "侯亮", "sex": "男", "age": 36, "city": "四川省 泸州市", "phone": "13556789023"},
{"id": 764802, "name": "白春梅", "sex": "女", "age": 38, "city": "广东省 佛山市", "phone": "15667890134"},
{"id": 875913, "name": "邹成", "sex": "男", "age": 44, "city": "湖北省 宜昌市", "phone": "17878901245"},
{"id": 986024, "name": "龙婷", "sex": "女", "age": 25, "city": "浙江省 宁波市", "phone": "13689012356"},
{"id": 109135, "name": "范志伟", "sex": "男", "age": 31, "city": "江苏省 苏州市", "phone": "15990123467"},
{"id": 210246, "name": "雷小雨", "sex": "女", "age": 29, "city": "福建省 厦门市", "phone": "18701234578"},
{"id": 321357, "name": "钟华", "sex": "男", "age": 37, "city": "山东省 青岛市", "phone": "13612345689"},
{"id": 432468, "name": "汪桂芳", "sex": "女", "age": 42, "city": "河南省 洛阳市", "phone": "15823456790"},
{"id": 543579, "name": "丁一鸣", "sex": "男", "age": 26, "city": "湖南省 株洲市", "phone": "18934567801"},
{"id": 654680, "name": "阳丽", "sex": "女", "age": 33, "city": "安徽省 芜湖市", "phone": "15745678912"},
{"id": 765791, "name": "傅国强", "sex": "男", "age": 44, "city": "江西省 九江市", "phone": "13156789023"},
{"id": 876802, "name": "周艳", "sex": "女", "age": 27, "city": "辽宁省 大连市", "phone": "18567890134"},
{"id": 987913, "name": "覃敏", "sex": "女", "age": 36, "city": "陕西省 宝鸡市", "phone": "15378901245"},
{"id": 108024, "name": "龚浩", "sex": "男", "age": 23, "city": "贵州省 遵义市", "phone": "18689012356"},
{"id": 219135, "name": "汤圆圆", "sex": "女", "age": 30, "city": "云南省 大理州", "phone": "13590123467"},
{"id": 320246, "name": "邵伟杰", "sex": "男", "age": 35, "city": "广西壮族自治区 桂林市", "phone": "15801234578"},
{"id": 431357, "name": "秦淑珍", "sex": "女", "age": 41, "city": "甘肃省 天水市", "phone": "13612345689"},
{"id": 542468, "name": "曾超", "sex": "男", "age": 28, "city": "青海省 海东市", "phone": "18723456790"},
{"id": 653579, "name": "兰海燕", "sex": "女", "age": 26, "city": "海南省 三亚市", "phone": "15534567801"},
{"id": 764680, "name": "白俊峰", "sex": "男", "age": 39, "city": "内蒙古自治区 包头市", "phone": "13145678912"},
{"id": 875791, "name": "温丽娟", "sex": "女", "age": 35, "city": "新疆维吾尔自治区 喀什地区", "phone": "15656789023"},
{"id": 986802, "name": "岑龙", "sex": "男", "age": 24, "city": "宁夏回族自治区 石嘴山市", "phone": "18867890134"},
{"id": 107913, "name": "全红梅", "sex": "女", "age": 32, "city": "西藏自治区 日喀则市", "phone": "13478901245"},
{"id": 218024, "name": "骆天宇", "sex": "男", "age": 30, "city": "北京市 北京市", "phone": "15689012356"},
{"id": 329135, "name": "阮诗涵", "sex": "女", "age": 22, "city": "上海市 上海市", "phone": "18790123467"},
{"id": 430246, "name": "凌志远", "sex": "男", "age": 45, "city": "江苏省 无锡市", "phone": "13301234578"},
{"id": 541357, "name": "覃玉婷", "sex": "女", "age": 28, "city": "浙江省 温州市", "phone": "15512345689"},
{"id": 652468, "name": "蒲剑锋", "sex": "男", "age": 33, "city": "湖北省 襄阳市", "phone": "18623456790"},
]
任务清单:
-
遍历
staff列表,用 f-string 输出每位员工的姓名和年龄,格式为姓名: xxx, 年龄: xx -
创建一个新列表
female_staff,装下所有性别为"女"的员工(即sex键的值为"女") -
创建一个新列表
young_female,装下所有年龄小于 30 岁的女员工 -
创建一个新列表
zhou_staff,装下所有姓"周"的员工(提示:name[0]可以取出姓名的第一个字) -
创建一个新列表
phone_tail_3,装下所有手机号尾号是 "3" 的员工(提示:字符串支持负索引,phone[-1]取最后一个字符) -
创建一个新列表
all_names,装下所有员工的姓名 -
创建一个新列表
female_names,装下所有女员工的姓名 -
创建一个新列表
female_contacts,其中每个元素是一个字典,只保留name和phone两个键,且只收录女员工 -
计算并打印全体员工的年龄总和
-
计算并打印全体员工的平均年龄(保留两位小数,用 f-string 格式化)
-
创建一个字典
result,包含两个键:"names"对应所有员工姓名组成的列表,"ages"对应所有员工年龄组成的列表 -
找到
id为520318的员工,打印其姓名和手机号。如果找不到,打印"查无此人" -
判断员工中是否存在年龄大于 40 岁的男员工。如果存在,打印
True并输出该员工的姓名;否则打印False -
判断是否所有女员工的年龄都在 40 岁以内(即没有超过 40 岁的女员工)。如果是,打印
True;否则打印False