could sum be faster on lists

后端 未结 3 1225
一生所求
一生所求 2020-12-07 02:11

This is somehow a follow-up to this question

So first, you\'ll notice that you cannot perform a sum on a list of strings to concatenate them, python tel

相关标签:
3条回答
  • 2020-12-07 02:34
    /* It's tempting to use PyNumber_InPlaceAdd instead of
               PyNumber_Add here, to avoid quadratic running time
               when doing 'sum(list_of_lists, [])'.  However, this
               would produce a change in behaviour: a snippet like
                 empty = []
                 sum([[x] for x in range(10)], empty)
               would change the value of empty. */
    temp = PyNumber_Add(result, item);
    

    Taken from Python's built-in source code https://github.com/python/cpython/blob/master/Python/bltinmodule.c#L2146 Line:2342

    0 讨论(0)
  • 2020-12-07 02:47

    FWIW, we can trick the interpreter into letting us use sum on strings by passing an appropriate custom class instance as the start arg to sum.

    class Q(object):
        def __init__(self, data=''):
            self.data = str(data)
    
        def __str__(self):
            return self.data
    
        def __add__(self, other):
            return Q(self.data + str(other))
    
    print(sum(['abc', 'def', 'ghi'], Q()))
    

    output

    abcdefghi
    

    Of course, this is a rather silly thing to do. :)

    0 讨论(0)
  • 2020-12-07 02:56

    We could try to make sum() smarter, but Alex Martelli and Guido van Rossum wanted to keep it focused on arithmetic summations.

    FWIW, you should get reasonable performance with this simple code:

    result = []
    for seq in mylists:
        result += seq
    

    For your other question, "why can't sum use this accumulative approach when available?", see this comment for builtin_sum() in Python/bltinmodule.c:

        /* It's tempting to use PyNumber_InPlaceAdd instead of
           PyNumber_Add here, to avoid quadratic running time
           when doing 'sum(list_of_lists, [])'.  However, this
           would produce a change in behaviour: a snippet like
    
             empty = []
             sum([[x] for x in range(10)], empty)
    
           would change the value of empty. */
    
    0 讨论(0)
提交回复
热议问题