ZetCode

Python sum 函数

上次修改时间:2025 年 4 月 11 日

这份综合指南探讨了 Python 的 sum 函数,该函数返回可迭代对象中所有项的总和。我们将涵盖数字类型、起始值以及求和运算的实际示例。

基本定义

sum 函数将可迭代对象中的所有项从左到右相加,并返回总和。它接受一个可选的 start 参数,该参数默认为 0。

关键特性:适用于包含可加项(数字、列表、元组)的任何可迭代对象。start 值确定求和的初始值。

基本数值求和

这是一个使用不同数字类型的简单示例,展示了 sum 如何处理整数、浮点数和混合数字的列表。

basic_sum.py
# Summing integers
numbers = [1, 2, 3, 4, 5]
print(sum(numbers))  # 15

# Summing floats
prices = [9.99, 14.95, 4.50]
print(sum(prices))   # 29.44

# Mixed numeric types
mixed = [10, 3.5, 2.5, 4]
print(sum(mixed))    # 20.0

此示例展示了具有不同数值可迭代对象的 sum。它可以自动处理整数、浮点数和混合类型,并自动转换结果。

混合类型示例返回 20.0(浮点数),因为 Python 会将结果提升为序列中最精确的数值类型。

使用 Start 参数

可选的 start 参数允许为求和设置一个初始值。这对于累加器或在对非零基序列求和时非常有用。

start_param.py
# Basic start value
numbers = [1, 2, 3]
print(sum(numbers, 10))  # 16 (10 + 1 + 2 + 3)

# Concatenating lists
lists = [[1, 2], [3, 4], [5, 6]]
print(sum(lists, []))    # [1, 2, 3, 4, 5, 6]

# Building strings
words = ["Hello", " ", "World"]
print(sum(words, ""))    # "Hello World"

第一个示例展示了带有起始值的数值求和。其他示例演示了 start 在列表连接和字符串构建中的创造性用法。

请注意,虽然这些技术有效,但像 ''.join() 这样的专用字符串方法通常更具可读性和效率。

对自定义对象求和

您可以通过实现 __add__ 方法来对自定义对象求和。此示例创建了一个可以求和的 Money 类。

custom_sum.py
class Money:
    def __init__(self, amount):
        self.amount = amount
    
    def __add__(self, other):
        return Money(self.amount + other.amount)
    
    def __radd__(self, other):
        return self.__add__(other)
    
    def __repr__(self):
        return f"Money({self.amount})"

transactions = [Money(100), Money(50), Money(25)]
total = sum(transactions, Money(0))
print(total)  # Money(175)

Money 类实现了 __add____radd__ 以支持求和。我们提供 Money(0) 作为起始值以进行正确的初始化。

这种模式对于金融应用程序或任何需要对自定义类似数值对象求和的领域都很有用。

错误处理

当与不可加的类型一起使用时,sum 函数会引发 TypeError。此示例展示了正确的错误处理。

errors.py
try:
    print(sum(["a", "b", "c"]))
except TypeError as e:
    print(f"Error: {e}")  # unsupported operand type(s) for +: 'int' and 'str'

class NoAdd:
    pass

try:
    print(sum([NoAdd(), NoAdd()]))
except TypeError as e:
    print(f"Error: {e}")  # unsupported operand type(s) for +: 'int' and 'NoAdd'

这些示例演示了 sum 在不支持的类型中的行为。字符串和没有 __add__ 的对象会引发 TypeError

要使一个类与 sum 一起使用,请如前面的示例所示实现 __add__

性能注意事项

此示例比较了 sum 性能与用于对数字求和的替代方法。

performance.py
import timeit
import numpy as np

def test_sum():
    return sum(range(1000))

def test_for_loop():
    total = 0
    for i in range(1000):
        total += i
    return total

def test_numpy():
    return np.sum(np.arange(1000))

print("sum():", timeit.timeit(test_sum, number=10000))
print("for loop:", timeit.timeit(test_for_loop, number=10000))
print("numpy:", timeit.timeit(test_numpy, number=10000))

这会比较不同的求和方法。对于内置类型,sum 通常是最快的。对于非常大的数据集,NumPy 可能会更快。

for 循环方法通常较慢,这表明为什么在大多数情况下首选 sum

最佳实践

资料来源

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。到目前为止,我已经撰写了超过 1400 篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

列出所有 Python 教程