Pythonic总结列表和列表列表的方法

时间:2010-01-21 04:50:00

标签: algorithm python

我正在尝试找到一个简洁的方法来汇总列表和同一个函数中的列表列表,到目前为止我已经得到了:

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]])

...但这些似乎都不适合我(doc字符串中的原因)。我想知道的是,如果有更好的方法来汇总列表和列表列表,这些列表和列表不需要我捕获异常或在函数决定要做什么之前实际分析列表。

显然,我仍然期望['a', 'b']无效。

3 个答案:

答案 0 :(得分:5)

也许您会发现首先展平列表会更容易?

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

有了上述内容,您可以这样做:

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]

答案 1 :(得分:3)

不要忘记准确描述您要做的事情。我假设你的意思是将所有值加总为单个值,而不是得到例如。 [[1,2],[3,4]] - > [3,7]。这是简单的递归;如果你跳过测试,可以输入五行代码:

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()

答案 2 :(得分:0)

外部numpy模块有许多操作(包括sum()),它们在标量,向量,矩阵甚至更高维数组上的工作方式类似......

但请注意,它不适用于[1,2,[3,4,5]]等混合列表,只适用于方形矩阵!所以它并没有完全回答你的问题。