专项练习 · 7 分钟阅读

Python 排序练习:key、reverse 与记录排序

给数字列表排序只是第一步。真正有用的是按指定字段排序记录,同时保留原始数据。

sorted 还是 sort?

sorted 返回新列表;sort 修改原列表并返回 None。根据原顺序是否还有用来选择。排序前后各打印一次,就能看清区别。

prices = [6.0, 4.5, 3.25]
print(sorted(prices))
print(prices)

新列表与原列表

按字段排序记录

传入一个 key 函数,返回要比较的字段。短规则用 lambda 就够了。记录本身不会改变;Python 只在排序时使用返回的键。

orders = [("latte", 4.5), ("tea", 3.0), ("mocha", 5.0)]
for name, price in sorted(orders, key=lambda item: item[1]):
    print(name, price)

按价格排序

倒序与极值

reverse=True 会反转顺序。min 和 max 返回元素,而不是排序列表。记录需要比较时,给 min 或 max 也传 key,指定按哪个字段取极值。

prices = [4.5, 6.0, 3.25]
print(sorted(prices, reverse=True))
print(max(prices))

降序与最大值

用 zip 与 enumerate 配对数据

zip 把同一位置的值配对,enumerate 添加索引。报表既需要行号又需要两个相关字段时,可以组合使用。长度不一致时,以较短的序列为准。

names = ["latte", "tea"]
prices = [4.5, 3.0]
for i, (name, price) in enumerate(zip(names, prices), 1):
    print(i, name, price)

带编号的配对

保留稳定的次级排序

需要多个字段时,key 可以返回元组。Python 先比较第一个元素,再比较下一个。这样就能按价格、再按名称排序,而不用写自定义比较函数。

orders = [("latte", 4.5), ("tea", 4.5), ("mocha", 3.0)]
print(sorted(orders, key=lambda item: (item[1], item[0])))

先价格,再名称

你的练习清单

常见问题

为什么列表变成了 None?

你可能把 sort() 的结果赋回了列表。单独调用 items.sort(),或者用 items = sorted(items)。

怎样按元组的第二项排序?

用 key=lambda item: item[1]。lambda 返回 Python 应该比较的字段。

zip 会按较长的列表继续吗?

不会。zip 在最短输入耗尽时停止,缺失的值会被静默忽略。

练习排序

12 道题,覆盖 sorted、sort、key 函数、reverse、zip 和 enumerate。

打开练习

继续阅读: