pin_drop当前位置:知识文库 ❯ 图文

Python reversed sorted sum函数

一、reversed()反向迭代器

reversed() 是Python内置函数,用于创建一个反向迭代器。它不会修改原序列,而是返回一个迭代器,按逆序遍历元素。适用于列表、元组、字符串和任何实现了 __reversed__()__getitem__()__len__() 的对象。

示例1:基本用法

代码示例

# 列表反转
numbers = [1, 2, 3, 4, 5]
rev_iter = reversed(numbers)

print(f"原列表: {numbers}")
print(f"反向迭代器: {list(rev_iter)}")

# 直接在for循环中使用
print("倒序遍历:")
for num in reversed(numbers):
    print(num, end=" ")
# 输出: 5 4 3 2 1

# 输出结果
# 原列表: [1, 2, 3, 4, 5]
# 反向迭代器: [5, 4, 3, 2, 1]
# 倒序遍历:
# 5 4 3 2 1

示例2:字符串和元组

代码示例

# 字符串反转
text = "Python"
reversed_text = "".join(reversed(text))
print(f"原字符串: {text}")
print(f"反转后: {reversed_text}")

# 元组反转
tup = (10, 20, 30, 40)
reversed_tup = tuple(reversed(tup))
print(f"原元组: {tup}")
print(f"反转后: {reversed_tup}")

# 输出结果
# 原字符串: Python
# 反转后: nohtyP
# 原元组: (10, 20, 30, 40)
# 反转后: (40, 30, 20, 10)

二、reversed()与切片[::-1]对比

Python中反转序列有两种常见方式:reversed() 和切片 [::-1]。两者在使用场景和性能上有所不同。

示例1:性能对比

代码示例

import time

data = list(range(1000000))

# 方式1:reversed() - 返回迭代器,惰性求值
start = time.time()
rev1 = reversed(data)
# 只创建迭代器,不立即复制数据
time1 = time.time() - start
print(f"reversed()创建时间: {time1:.6f}秒")

# 方式2:切片[::-1] - 创建新列表
start = time.time()
rev2 = data[::-1]
# 立即复制整个列表
time2 = time.time() - start
print(f"切片[::-1]创建时间: {time2:.6f}秒")

print(f"结果相同: {list(rev1) == rev2}")

# 输出结果(因机器而异)
# reversed()创建时间: 0.000001秒(极快)
# 切片[::-1]创建时间: 0.012345秒(需要复制)
# 结果相同: True

提示:如果只是遍历而不需要新列表,优先使用 reversed(),因为它返回迭代器,内存效率更高。如果需要一个新的反转列表,使用切片 [::-1] 更简洁。

三、sorted()排序函数

sorted() 是Python内置的排序函数,对任意可迭代对象进行排序并返回新的列表。与列表的 sort() 方法不同,sorted()不会修改原对象,而是返回一个排序后的新列表。

代码示例

# sorted()函数语法
sorted(iterable, key=None, reverse=False)

# 参数说明:
# iterable - 可迭代对象
# key      - 可选,自定义排序规则函数
# reverse  - 可选,是否降序(默认False为升序)

示例1:基础排序

代码示例

# 数字排序
numbers = [64, 34, 25, 12, 22, 11, 90]
sorted_numbers = sorted(numbers)

print(f"原列表: {numbers}")
print(f"升序排序: {sorted_numbers}")
print(f"原列表未修改: {numbers}")

# 降序排序
desc_numbers = sorted(numbers, reverse=True)
print(f"降序排序: {desc_numbers}")

# 输出结果
# 原列表: [64, 34, 25, 12, 22, 11, 90]
# 升序排序: [11, 12, 22, 25, 34, 64, 90]
# 原列表未修改: [64, 34, 25, 12, 22, 11, 90]
# 降序排序: [90, 64, 34, 25, 22, 12, 11]

示例2:字符串排序

代码示例

# 字符串按字典序排序
words = ["banana", "apple", "cherry", "date"]
sorted_words = sorted(words)
print(f"字典序排序: {sorted_words}")

# 按长度排序
sorted_by_len = sorted(words, key=len)
print(f"按长度排序: {sorted_by_len}")

# 忽略大小写排序
mixed_case = ["Banana", "apple", "Cherry", "date"]
sorted_ignore_case = sorted(mixed_case, key=str.lower)
print(f"忽略大小写: {sorted_ignore_case}")

# 输出结果
# 字典序排序: ['apple', 'banana', 'cherry', 'date']
# 按长度排序: ['date', 'apple', 'banana', 'cherry']
# 忽略大小写: ['apple', 'Banana', 'Cherry', 'date']

四、sorted()高级排序技巧

示例1:字典列表排序

代码示例

# 学生数据
students = [
    {"name": "张三", "score": 85, "age": 20},
    {"name": "李四", "score": 92, "age": 19},
    {"name": "王五", "score": 78, "age": 21},
    {"name": "赵六", "score": 92, "age": 20},
]

# 按分数降序
by_score = sorted(students, key=lambda x: x["score"], reverse=True)
print("按分数降序:")
for s in by_score:
    print(f"  {s['name']}: {s['score']}分")

# 多条件排序:先按分数降序,再按年龄升序
by_score_age = sorted(students, key=lambda x: (-x["score"], x["age"]))
print("\n按分数降序,年龄升序:")
for s in by_score_age:
    print(f"  {s['name']}: {s['score']}分, {s['age']}岁")

# 输出结果
# 按分数降序:
#   李四: 92分
#   赵六: 92分
#   张三: 85分
#   王五: 78分
#
# 按分数降序,年龄升序:
#   李四: 92分, 19岁
#   赵六: 92分, 20岁
#   张三: 85分, 20岁
#   王五: 78分, 21岁

示例2:operator模块排序

代码示例

from operator import itemgetter, attrgetter

# 使用itemgetter排序(比lambda更快)
students = [
    ("张三", 85, 20),
    ("李四", 92, 19),
    ("王五", 78, 21),
]

# 按分数(索引1)排序
by_score = sorted(students, key=itemgetter(1), reverse=True)
print(f"按分数排序: {by_score}")

# 多条件排序
by_score_age = sorted(students, key=itemgetter(1, 2))
print(f"按分数和年龄排序: {by_score_age}")

# 输出结果
# 按分数排序: [('李四', 92, 19), ('张三', 85, 20), ('王五', 78, 21)]
# 按分数和年龄排序: [('王五', 78, 21), ('张三', 85, 20), ('李四', 92, 19)]

五、sum()求和函数

sum() 是Python内置的求和函数,用于计算可迭代对象中所有元素的总和。它支持数字类型(int、float、complex),并且可以通过start参数指定初始值。

示例1:基础求和

代码示例

# 整数求和
numbers = [1, 2, 3, 4, 5]
total = sum(numbers)
print(f"列表: {numbers}")
print(f"总和: {total}")

# 浮点数求和
floats = [1.5, 2.5, 3.0, 4.5]
float_total = sum(floats)
print(f"浮点数列表: {floats}")
print(f"浮点数总和: {float_total}")

# 元组求和
tup = (10, 20, 30)
tup_sum = sum(tup)
print(f"元组总和: {tup_sum}")

# 输出结果
# 列表: [1, 2, 3, 4, 5]
# 总和: 15
# 浮点数列表: [1.5, 2.5, 3.0, 4.5]
# 浮点数总和: 11.5
# 元组总和: 60

示例2:生成器表达式求和

代码示例

# 计算1到100的和
sum_100 = sum(range(1, 101))
print(f"1到100的和: {sum_100}")

# 计算平方和
sum_squares = sum(x**2 for x in range(1, 6))
print(f"1^2 + 2^2 + 3^2 + 4^2 + 5^2 = {sum_squares}")

# 条件求和:计算偶数和
sum_evens = sum(x for x in range(1, 11) if x % 2 == 0)
print(f"1到10中偶数的和: {sum_evens}")

# 输出结果
# 1到100的和: 5050
# 1^2 + 2^2 + 3^2 + 4^2 + 5^2 = 55
# 1到10中偶数的和: 30

六、sum()的start参数

sum(iterable, start) 的第二个参数 start 用于指定求和的初始值。最终结果等于 start + sum(iterable)

示例1:基础start用法

代码示例

# 带初始值求和
numbers = [1, 2, 3, 4, 5]

result1 = sum(numbers, 10)
print(f"sum([1,2,3,4,5], 10) = {result1}")

result2 = sum(numbers, 100)
print(f"sum([1,2,3,4,5], 100) = {result2}")

# 输出结果
# sum([1,2,3,4,5], 10) = 25
# sum([1,2,3,4,5], 100) = 115

示例2:列表拼接(不推荐)

代码示例

# sum()可以用于列表拼接(但效率低)
lists = [[1, 2], [3, 4], [5, 6]]

# 使用sum()拼接
flattened = sum(lists, [])
print(f"拼接结果: {flattened}")

# 推荐方式:使用itertools.chain或列表推导式
from itertools import chain
flattened_chain = list(chain.from_iterable(lists))
print(f"chain拼接: {flattened_chain}")

# 输出结果
# 拼接结果: [1, 2, 3, 4, 5, 6]
# chain拼接: [1, 2, 3, 4, 5, 6]

注意:虽然 sum(lists, []) 可以拼接列表,但时间复杂度为O(n^2),效率很低。对于大量列表拼接,推荐使用 itertools.chain.from_iterable() 或列表推导式 [item for sublist in lists for item in sublist]

七、三函数对比表格

对比项 reversed() sorted() sum()
功能 反向迭代器 排序返回新列表 求和
返回值类型 迭代器 list 数字类型
修改原对象
常用参数 key, reverse start
内存效率 高(迭代器) 中(创建新列表)

八、注意事项

  • reversed()返回迭代器:reversed()返回的是迭代器对象,只能遍历一次。如果需要多次使用,需转换为列表:list(reversed(data))

  • sorted()稳定性:Python的sorted()使用Timsort算法,是稳定排序。相等元素的相对顺序在排序后保持不变。

  • sum()类型限制:sum()只能用于数值类型求和,不能用于字符串拼接。字符串拼接应使用 "".join()

  • 浮点数精度:对于大量浮点数求和,可能存在精度损失。需要高精度时可使用 math.fsum()


小贴士

链式调用:这三个函数可以链式调用实现复杂操作。例如 sum(sorted(numbers, reverse=True)[:5]) 可以计算前5大数的和。list(reversed(sorted(data))) 等价于 sorted(data, reverse=True),但后者更高效。

常见问题

reversed()和list.reverse()有什么区别?

reversed()返回一个新的迭代器,不修改原列表,适用于任何可迭代对象。list.reverse()是列表的原地方法,直接修改原列表并返回None,只适用于列表。如果需要保留原数据,使用reversed();如果不需要原数据,使用reverse()更节省内存。

sorted()和list.sort()应该用哪个?

如果需要保留原列表,使用sorted();如果不需要原列表且对象是列表,使用list.sort()更节省内存。sorted()适用于任何可迭代对象,list.sort()只适用于列表。两者使用相同的Timsort算法,性能相当。

sum()的start参数有什么实际用途?

start参数常用于设置基准值或偏移量。例如计算总分时加上基础分:sum(scores, base_score)。也可以用于累积计算,如 sum(new_items, len(existing_items)) 计算总数。

如何提高浮点数求和的精度?

对于大量浮点数求和,使用 math.fsum() 代替sum()。fsum()使用扩展精度算法,能避免浮点数累加时的精度损失。例如:math.fsum([0.1] * 10) 返回精确的1.0。

十一、练习题

练习1

给定一个包含学生信息的列表,每个学生是字典 {"name": str, "scores": list}。编写函数 get_top_students(students, n=3),返回总分排名前n的学生名单。要求:(1) 使用sum()计算总分;(2) 使用sorted()排序;(3) 返回包含姓名和总分的新列表。编写完整代码并测试。

练习2

编写函数 palindrome_checker(text),检查文本是否为回文(忽略大小写和空格)。要求使用reversed()实现,不使用切片。编写完整代码并测试,包含 "A man a plan a canal Panama" 等测试用例。

标签: reversed函数 sorted函数 sum函数 Python内置函数 迭代器 排序 Python教程

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: Python pow和round函数 - 幂运算四舍五入 下一篇: Python zip函数

poll相关推荐