为什么python';s sum()是否需要开始参数?

为什么python';s sum()是否需要开始参数?,python,python-3.x,Python,Python 3.x,Python的sum()函数非常有用且通用,除了它对start参数(sum(iterable,/,start=0))的要求之外,该参数默认为0。这样,我们只能对支持整数加法的可数进行求和。否则,我们将显式地定义start。这会影响可读性,有时会导致不必要的计算 考虑以下示例:假设我们想要对一些非平凡对象的iterable求和,例如Symphy的矩阵(如果不熟悉Symphy,可以将sp.Matrix视为支持求和但不支持整数的对象)。以下代码将失败: import sympy as sp a = s

Python的
sum()
函数非常有用且通用,除了它对
start
参数(
sum(iterable,/,start=0)
)的要求之外,该参数默认为0。这样,我们只能对支持整数加法的可数进行求和。否则,我们将显式地定义start。这会影响可读性,有时会导致不必要的计算

考虑以下示例:假设我们想要对一些非平凡对象的iterable求和,例如Symphy的矩阵(如果不熟悉Symphy,可以将
sp.Matrix
视为支持求和但不支持整数的对象)。以下代码将失败:

import sympy as sp
a = sp.Matrix([1, 2])
b = sp.Matrix([3, 4])
sum([a, b]) #TypeError: cannot add <class 'sympy.matrices.dense.MutableDenseMatrix'> and <class 'int'>
然而,这仅仅是因为我们可以定义一些零元素的类似物。如果我们无法做到这一点,那么实现另一个通用的
sum()
,而不需要对start进行要求,比每次都尝试寻找不同的“start”要容易得多。此外,若矩阵的大小很大,乘以零可能是一个相当昂贵的操作。从一开始创建零矩阵需要一些代码行。尽管
sum()
的目的是减少样板文件的数量

因此,问题是:

  • 他们为什么会想到这场争论呢?这怎么会有帮助呢?至少,他们可以让它成为
    start=None
    ,然后检查求和是否应该从iterable的第一个元素开始(如果
    start==None
    ),或者从
    start
    开始
  • 处理这种情况的最佳方法是什么
  • 您可以在此处阅读类似投诉的讨论:
  • 如果您确信所求和的内容永远不会为空,请使用:
  • 所以你可以对任意类型的可数求和。没有任何协议规定可以使用
    type(val)(
    作为值的安全默认值构造函数,因此Python没有这样做
  • 要知道要求和的内容,以便知道从何处开始,和/或找到一个函数,该函数可以在程序范围内计算出合适的
    start=

  • start
    之所以存在,是因为空和对支持很重要,并且没有起始值就无法支持空和。如果没有起始值,这将简化异常类型的保证非空和,但代价是使可能的空和变得更加尴尬


    可能的空和比具有异常类型的
    sum
    调用要常见得多,而且大多数具有异常类型的
    sum
    调用可能都是空的,因此它们仍然需要
    start

    参见内置函数的思想是支持所有用户的最广泛使用。这是设计师的决定。我对Symphy不太熟悉,但您是否尝试过
    sum([a,b],start=sp.Matrix())
    ?1。堆栈溢出不是讨论Python语言发明者的设计决策的合适场所。2.
    functools.reduce()
    。它不是为灵活而设计的,如果您查看其文档,它会声明“此函数专门用于数值,可能会拒绝非数值类型。”
    sum
    不是通用的“映射到iterable”工具。它明确地不支持
    str
    ,甚至对于
    float
    ,通常也不建议使用它,因为。如果你不得不担心你的零元素是否足够便宜,
    sum
    是不合适的。我是唯一一个断开这个链接的人吗?从文档中可以看出,reduce似乎是一个很好的通用决策@heinwol是的,这个链接对我有用,即使是在私人浏览中
    from typing import List
    
    def sum_matrices(ms: List[sp.Matrix]) -> sp.Matrix:
        return sum(ms, 0*ms[0])
    
    functools.reduce(operator.add, ms)