Contar quantos elementos de uma lista são menores do que um elemento de referência.
A solução trivial passa por percorrer (recorrendo a um ciclo) a lista e ir contando sempre que aparecer um elemento menor (uso de um acumulador. Mas mesmo esta situação pode ser feita de diferentes maneiras: percorrer a lista por índice ou percorrer por conteúdo:
def conta_menores1(num,lista_num): acum = 0 for i in range(len(lista_num)): if lista_num[i] < num: acum += 1 return acum def conta_menores2(num,lista_num): acum = 0 for i in lista_num: if i < num: acum += 1 return acumA segunda versão é a preferível do ponto de vista da eficiência, sendo que, na nossa opinião, é mais clara. Quem conhecer o conceito de listas por compreensão pode sugerir outra solução:
def conta_menores3(num, lista_num): return sum([ 1 for i in lista_num if i < num])Será que podemos arranjar ainda outra solução. Na aula um aluno sugeriu uma alternativa muito interessante:
def conta_menores4(num, lista_num): lista_num.sort() return lista_num.index(num)Nesta solução ordenamos a lista e depois calculamos a posição do número da lista que vai ser igual ao número de elementos menores. Mas esta solução tem um problema: só funciona se o número de referência estiver na lista. Consegue perceber porquê?? Tratemos agora de uma variante deste problema.
Listagem dos menores
Podemos ter soluções semelhantes às anteriores. O que muda é a natureza do acumulador (agora terá que ser um contentor, tuplo ou lista.
def lista_menores1(num,lista_num): acum = [] for i in range(len(lista_num)): if lista_num[i] < num: acum += [lista_num[i]] return acum def lista_menores2(num,lista_num): acum = [] for i in lista_num: if i < num: acum += [i] return acumAqui podemos variar a forma de juntar o elemento à lista, recorrendo ao método append em substituição da operação de concatenação:
def lista_menores3(num,lista_num): acum = [] for i in range(len(lista_num)): if lista_num[i] < num: acum.append(lista_num[i]) return acum def lista_menores4(num,lista_num): acum = [] for i in lista_num: if i < num: acum.append(i) return acumE uma vez mais a solução com listas por compreensão (a nossa preferida):
def lista_menores5(num, lista_num): return [i for i in lista_num if i < num]Será que a sugestão do nosso aluno também se aplica aqui (no pressuposto de que o elemento está na lista)? Claro:
def lista_menores4(num,lista_num): lista_num.sort() return lista_num[:lista_num.index(num)]
Soma cumulativa
Agora a questão é a de dada uma lista construir uma nova lista em que na posição i vamos ter a soma dos elementos da lista original entre as posições inicial e i (inclusivé). A solução mais simples baseia-se no recurso ao padrão ciclo-acumulador que contem no interior do ciclo outro padrão ciclo-acumulador. Este último é usado para o cálculo da soma cumulativa.
def soma_cumulativa(lista): acum = [] for i in range(len(lista)): # soma de 0 a i soma = 0 for j in range(i+1): soma += lista[j] # junta soma ao acumulador acum.append(soma) return acumConhecendo a existência da função sum podemos simplificar a nossa primeira solução:
def soma_cumulativa2(lista): acum = [] for i in range(len(lista)): # soma de 0 a i soma = sum(lista[:i+1]) # junta soma ao acumulador acum.append(soma) return acumE, também aqui, o recurso a listas por compreensão da origem a um programa mais curto:
def soma_cumulativa3(lista): return [sum(lista[:i+1]) for i in range(len(lista))]Será que podemos fazer melhor? Podemos. Uma pequena reflexão sobre o problema mostra que existe uma relação simples entre duas somas cumulativas consecutivas: basta somar à soma anterior (de 0 a i) o valor do elemento na posição (i+1):
def soma_cumulativa4(lista): acum = [lista[0]] for i in lista[1:]: acum.append(acum[-1]+i) return acumE pronto. Esperamos que tenham ficado com uma ideia de que em programação mesmo os problemas mais simples podem ter várias alternativas.
Sem comentários:
Enviar um comentário