Pythonic способ суммирования списков и списков списков - PullRequest
1 голос
/ 21 января 2010

Я пытаюсь найти аккуратный способ суммирования списка и списка списков в одной и той же функции, пока у меня есть:

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

... но ни один из них не кажется мне совершенно правильным (причины в строках документа). Я хочу знать, есть ли лучший способ суммирования списков и списков списков, который не требует, чтобы я перехватывал исключения или фактически анализировал список, прежде чем функция решит, что делать.

Очевидно, я все еще ожидаю, что ['a', 'b'] будет недействительным.

Ответы [ 3 ]

5 голосов
/ 21 января 2010

Может быть, вам сначала будет проще сгладить список?

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]
3 голосов
/ 21 января 2010

Не забудьте точно описать, что вы пытаетесь сделать. Я предполагаю, что вы хотите суммировать все значения в одно значение, а не получить, например. [[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()
0 голосов
/ 23 января 2010

Внешний модуль numpy имеет много операций (в том числе sum () ), которые аналогично работают со скалярами, векторами, матрицами и даже многомерными массивами ...

Обратите внимание, что он не работает со смешанными списками, такими как [1,2,[3,4,5]], только с квадратными матрицами! Так что это не совсем отвечает на ваш вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...