Processing math: 100%

4.3. Calculando a Soma de Uma Lista de Números

Nós vamos iniciar nossa investigação com um problema simples que você já sabe resolver sem usar recursão. Imagine que você queira calcular a soma de uma lista de números tal como: [1,3,5,7,9]. Uma função iterativa que calcula a soma é mostrada no ActiveCode 1. A função usa uma variável acumuladora (“soma”) que calcula a somatória de todos os números da lista começando com 0 e adicionando cada número da lista.

 
1
def somalista(numeros):
2
    soma = 0
3
    for i in numeros:
4
        soma = soma + i
5
    return soma
6
7
print(somalista([1,3,5,7,9]))
8

Somatória Iterativa (lst_itsum)

Imagine por um minuto que você não tem os comandos de repetição while e for. Como você calcularia a soma de uma lista de números? Se você fosse um matemático, você poderia começar lembrando que a adição é uma função definida par dois parâmetros, um par de números. Para redefinir o problema de adição de lista para adição de um par de números, podemos reescrever a lista como uma expressão com parênteses. Essa expressão poderia ser como essa:

((((1+3)+5)+7)+9)

Nós podemos também formar uma expressão com parênteses em ordem contrária:

(1+(3+(5+(7+9))))

Observe que o conjunto mais interno de parênteses, (7+9), é um problema que podemos resolver sem comandos de repetição ou qualquer construção especial. De fato, podemos usar a seguinte sequência de simplificações para calcular a soma final.

total= (1+(3+(5+(7+9))))total= (1+(3+(5+16)))total= (1+(3+21))total= (1+24)total= 25

Como podemos considerar essa ideia e aplicá-la em um programa em Python? Primeiro vamos considerar o problema de soma em termos de listas em Python. Podemos dizer que a soma da lista numeros é a soma do primeiro elemento da lista (numeros[0]), e a soma dos números do resto da lista (numeros[1:]). Para escrever isso em forma funcional:

somalista(numeros)=primeiro(numeros)+somalista(resto(numeros))

Nessa equação primeiro(numeros) retorna o primeiro elemento da lista resto(numeros) e retorna a lista menos o primeiro elemento. Isso é facilmente expresso em Python como mostrado no ActiveCode 2.

8
 
1
def somalista(numeros):
2
   if len(numeros) == 1:
3
        return numeros[0]
4
   else:
5
        return numeros[0] + somalista(numeros[1:])
6
7
print(somalista([1,3,5,7,9]))
8

Somatória Recursiva (lst_recsum)

Há algumas ideias básicas que devem ser observadas nesse código. Primeiro, na linha 2 nós verificamos se a lista possui apenas um elemento. Essa verificação é crucial e é a forma de sair da função. A soma de uma lista de comprimento 1 é trivial; é simplesmente o número que está na lista. Segundo, na linha 5, nossa função chama a si mesma! Essa é a razão pela qual chamamos o algoritmo sum de recursivo. Uma função recursiva é uma função que chama a si mesma.

A figura 1 mostra a série de chamadas recursivas necessárias para somar a lista [1,3,5,7,9]. Você deve considerar essa série de chamadas como um série de simplificações. Cada vez que fazemos uma chamada recursiva estamos resolvendo um problema menor, até chegar a um ponto onde o problema não precisa mais ficar menor.

image

Figura 1: Série de chamadas recursivas para somar (sum) uma lista de números

Quando chegamos ao ponto onde o problema se torna tão simples quanto possível, passamos a montar as soluções de cada um dos problemas menores até resolver o problema inicial. A figura 2 mostra as adições realizadas a medida que sum vai retornando pela série de chamadas. Quando sum retorna da primeira chamada, nós obtemos a solução de todo o problema.

image

Figura 2: Série de returns das chamadas recursivas para somar (sum) uma lista de números

Next Section - 4.4. As Três Leis da Recursão