开发者

Pythonic way of summing lists and lists of lists

开发者 https://www.devze.com 2022-12-17 10:03 出处:网络
I\'m trying to find a neat way of summing a list and a list of lists in the same function, so far I\'ve got:

I'm trying to find a neat way of summing a list and a list of lists in the same function, so far I've got:

import operator
"""
 Fails late for item = ['a', 'b']
"""   
def validate(item):
    try:
        return sum(item) == sum(range(1, 10))
    except TypeError:
        return sum(reduce(operator.add, item)) == sum(range(1, 10))

"""
 Not valid for item = [1,2,[3,4,5]]
"""
def validate2(item):
        if isinstance(item[0], int):
            return sum(item) == sum(range(1, 10))
        else:
            return sum(reduce(operator.add, item)) == sum(range(1, 10))


print validate([1, 2, 3, 4, 5, 6, 7, 8, 9])
print validate([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

print validate2([1, 2, 3, 4, 5, 6, 7, 8, 9])
print validate2([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

...but neither of these seem quite right to me (reasons in the doc strings). What I want to know is if there is a better way of summin开发者_开发知识库g lists and lists of lists that doesn't require me to catch exceptions or actually analyse the list before the function decides what to do.

Obviously, I'm still expecting ['a', 'b'] to be invalid.


Perhaps you'd find it easier to flatten the list first?

def flatten(xs):
     for x in xs:
        try:
            sub = iter(x)
        except TypeError:
            yield x
        else:
            for y in flatten(sub):
                yield y

With the above, you can do this:

In [4]: fs = flatten([1,2,[3,4,[5,6],7],8,[9,10]])

In [5]: list(fs)
Out[5]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


Don't forget to describe exactly what you're trying to do. I'm assuming you mean to sum all values to a single value, and not to get eg. [[1,2],[3,4]] -> [3,7]. Here's simple recursion; five lines of code if you skip the tests:

def sums(it):
    """
    >>> sums(1)
    1
    >>> sums([1,2,3])
    6
    >>> sums([1,2,3,[4,5]])
    15
    >>> sums(['a','b'])
    Traceback (most recent call last):
    ...
    TypeError: unsupported operand type(s) for +: 'int' and 'str'
    """
    if getattr(it, "__iter__", None):
        return sum(map(sums, it))
    else:
        return it

if __name__ == "__main__":
    import doctest
    doctest.testmod()


The external numpy module has many operations (including sum()) which work similarly on scalars, vectors, matrices and even higher-dimensional arrays...

Note however that it doesn't work on mixed lists like [1,2,[3,4,5]], only square matrices! So it doesn't exactly answer your question.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号