Python求和,为什么不是字符串?

2024-04-26 13:01:01 发布

您现在位置:Python中文网/ 问答频道 /正文

Python有一个内置函数sum,它实际上相当于:

def sum2(iterable, start=0):
    return start + reduce(operator.add, iterable)

用于除字符串以外的所有类型的参数。它适用于数字和列表,例如:

 sum([1,2,3], 0) = sum2([1,2,3],0) = 6    #Note: 0 is the default value for start, but I include it for clarity
 sum({888:1}, 0) = sum2({888:1},0) = 888

为什么特别遗漏了字符串

 sum( ['foo','bar'], '') # TypeError: sum() can't sum strings [use ''.join(seq) instead]
 sum2(['foo','bar'], '') = 'foobar'

我似乎记得Python列表中讨论的原因,所以一个解释或一个链接到一个线程来解释就可以了

编辑:我知道标准方法是"".join。我的问题是,为什么对字符串使用sum的选项被禁止,而对列表则没有禁止

编辑2:尽管我认为,考虑到我得到的所有好答案,不需要这样做,但问题是:为什么求和对包含数字的iterable或包含列表但不包含字符串的iterable有效


Tags: the字符串列表forfooisbar数字
3条回答

这是来源:http://svn.python.org/view/python/trunk/Python/bltinmodule.c?revision=81029&view=markup

在内置的求和函数中,我们有以下代码:

     /* reject string values for 'start' parameter */
        if (PyObject_TypeCheck(result, &PyBaseString_Type)) {
            PyErr_SetString(PyExc_TypeError,
                "sum() can't sum strings [use ''.join(seq) instead]");
            Py_DECREF(iter);
            return NULL;
        }
        Py_INCREF(result);
    }

所以。。这就是你的答案

它在代码中被显式签入并被拒绝

如果使用适当的起始对象,实际上可以使用sum(..)来连接字符串!当然,如果你走到这一步,你已经足够理解如何使用"".join(..)

>>> class ZeroObject(object):
...  def __add__(self, other):
...   return other
...
>>> sum(["hi", "there"], ZeroObject())
'hithere'

Python试图阻止您对字符串进行“求和”。你应该加入他们:

"".join(list_of_strings)

它速度更快,占用的内存也更少

快速基准:

$ python -m timeit -s 'import operator; strings = ["a"]*10000' 'r = reduce(operator.add, strings)'
100 loops, best of 3: 8.46 msec per loop
$ python -m timeit -s 'import operator; strings = ["a"]*10000' 'r = "".join(strings)'
1000 loops, best of 3: 296 usec per loop

编辑(回答OP的编辑):至于为什么字符串被明显地“挑出”,我相信这只是一个针对常见情况进行优化的问题,以及实施最佳实践的问题:使用“”可以更快地连接字符串。连接,因此明确禁止sum上的字符串将向新手指出这一点

顺便说一句,这个限制“永远”存在,也就是说,自从sum作为内置函数(rev. 32347)添加以来

相关问题 更多 >