2013-02-17 3 views
4

Я пытаюсь подвести список вложенных элементовсумма вложенного списка в Python

например, номер = [1,3,5,6, [7,8]], сумма = 30

I написал следующий код

def nested_sum(L): 

    sum=0 
    for i in range(len(L)): 
     if (len(L[i])>1): 
      sum=sum+nested_sum(L[i]) 
     else: 
      sum=sum+L[i] 
    return sum 

Приведенный выше код дает следующее сообщение об ошибке: объект 'межд' типа не имеет LEN() Я также попытался Len ([L [я]]), до сих пор не работает

Кто-нибудь может помочь? BTW, это Python 3.3

+0

Попробуйте использовать одну из многочисленных функций [flatten] (http: // stackoverflow.com/questions/2158395/flatten-an-irregular-list-of-lists-in-python), размещенный здесь до сих пор, и просто 'sum (flatten (L))' – georg

+0

Для Python, если я использую рекурсивный вызов, нужно беспокоиться о том, чтобы занять слишком много времени, когда стек идет? Я знаю, для этой проблемы, я, вероятно, не буду беспокоиться об этом – Jin

+0

@Jin Это, вероятно, немного рано для этого, но если вы хотите уменьшить потребление памяти, используйте [генератор] (http://wiki.python.org/ moin/Generators). – 2rs2ts

ответ

18

Чтобы проверить, является ли элемент списком, вам необходимо использовать isinstance. Кроме того, вам может понадобиться перебрать фактический список, чтобы упростить работу.

def nested_sum(L): 
    total = 0 # don't use `sum` as a variable name 
    for i in L: 
     if isinstance(i, list): # checks if `i` is a list 
      total += nested_sum(i) 
     else: 
      total += i 
    return total 
+0

Ницца! Полностью избили меня. – nneonneo

2

Одним из вариантов решения с пониманием списка:

>>> sum(sum(x) if isinstance(x, list) else x for x in L) 
30 

Edit: А для списков с более чем двумя уровнями (ТНХ @Volatility):

def nested_sum(L): 
    return sum(nested_sum(x) if isinstance(x, list) else x for x in L) 
+1

Не будет работать с вложенными списками с более чем двумя уровнями, хотя – Volatility

5

Это, как правило, считается более pythonic до duck type, а не явной проверки типов. Нечто подобное будет принимать какие-либо Iterable, а не только списки:

def nested_sum(a) : 
    total = 0 
    for item in a : 
     try: 
      total += item 
     except TypeError: 
      total += nested_sum(item) 
    return total 
2

Я бы просуммировать уплощенную список:

def flatten(L): 
    '''Flattens nested lists or tuples with non-string items''' 
    for item in L: 
     try: 
      for i in flatten(item): 
       yield i 
     except TypeError: 
      yield item 


>>> sum(flatten([1,3,5,6,[7,8]])) 
30 
1

Пример использования фильтра и карты и рекурсии:

def islist(x): 
    return isintance(x, list) 

def notlist(x): 
    return not isinstance(x, list) 

def nested_sum(seq): 
    return sum(filter(notlist, seq)) + map(nested_sum, filter(islist, seq)) 

И здесь приведен пример сокращения и рекурсии

from functools import reduce 


def nested_sum(seq): 
    return reduce(lambda a,b: a+(nested_sum(b) if isintance(b, list) else b), seq) 

Пример использования простых старых рекурсий:

def nested_sum(seq): 
    if isinstance(seq[0], list): 
     head = nested_sum(seq[0]) 
    else: 
     head = seq[0] 
    return head + nested_sum(seq[1:]) 

Пример использование моделируемой рекурсии:

def nested_sum(seq): 
    stack = [] 
    stack.append(seq) 
    result = 0 
    while stack: 
     item = stack.pop() 
     if isinstance(item, list): 
      for e in item: 
       stack.append(e) 
     else: 
      result += item 
    return result 

Adjustment для обработки самосправочных списков остаются в качестве упражнения для читателя.

4

Быстрая рекурсии, которая использует лямбда для обработки вложенных списков:

rec = lambda x: sum(map(rec, x)) if isinstance(x, list) else x 

rec, применяется в списке, возвращает сумму (рекурсивно), по значению, возвращает значение.

result = rec(a) 
1

Этот код также работает.

def add_all(t): 
    total = 0 
    for i in t: 
     if type(i) == list: # check whether i is list or not 
      total = total + add_all(i) 
     else: 
      total += i 
    return total 
Смежные вопросы