Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Somar itens repetidos em uma lista

def ordena():
    soma = []

    arquivo = open("produto_vendas_visitas.txt", "r")

    for linha in arquivo:
        valores = linha.split(";")
        soma.append((valores[0], (int(valores[1])*2) + int(valores[2])))

    arquivo.close()

    # Ordenando a lista
    soma.sort(key=lambda x: x[1], reverse=True)

    # Imprimindo a lista
    for s in soma:
        print(s)

    arquivo = open('produtos_ordenados.txt', 'w')

    for s in soma:
        arquivo.write(str(s))

    arquivo.close()


if __name__ == '__main__':
    ordena()

A saída fica:

('ID-789', 197) ('ID-123', 174) ('ID-ABC', 174) ('ID-567', 112) ('ID-567', 84)

Os ID's 567 repetem, como faço para somar eles?

5 respostas
solução!

A sua variável soma é uma lista, e listas não fazem esse tipo de agrupamento por uma determinada chave (que pelo que entendi no seu exemplo seriam os ID's, p.e. 'ID-567', que você gostaria que estivesse agrupado).

Quando você executa o método append para uma lista ele apenas adiciona o item ao final da lista.

Como no seu exemplo da saída você gostaria que pra cada ID existisse um valor correspondente, a melhor estrutura de dados que representa esse mapeamento de uma chave num valor é um dicionário.

Um exemplo de como seria modificado o código utilizando-se um dicionário:

soma_dict = {}
for linha in arquivo:
    valores = linha.split(";")
    chave = valores[0]
    agregado_valores = (int(valores[1])*2) + int(valores[2]))    
    #Checar se já existe a chave no dicionario
    if chave in soma_dict : 
        soma_dict[chave] += agregado_valores
    else:
        soma_dict[chave] = agregado_valores

#Transforma o seu dicionario numa lista novamente para que voce faca ordenacao
soma = [(k, soma_dict[k]) for k in soma_dict.keys())

#restante do codigo
....

Arthur, muito obrigado. Ajudou bastante e era exatamente o que eu estava precisando. Vou estudar mais essa parte do dicionário.

Arthur, poderia explicar essa parte por favor?

soma = [(k, soma_dict[k]) for k in soma_dict.keys())

Claro!

Bom, eu só me aproveitei de um recurso bem interessante de processamento de listas em python chamado "list comprehension".

Em Java / C++ ou até mesmo em python um modo de fazer a transformação do nosso dicionario em uma lista poderia ser simplesmente um loop (for por exemplo) onde pra cada chave eu adicionaria na nossa lista a tupla (chave, valor) - que é o modo como você usava os itens da sua lista no sort.

O Python tem esse " sintaxe sugar" (elementos da sintaxe que auxiliam a gente) para construir listas. Essa sintaxe abstrai por baixo dos panos a execução desse loop e é uma abordagem bem mais declarativa ( dizemos o nosso objetivo e ele se vira pra resolver pra gente). Se você reparar na escrita parece bastante com um humano falando o que ele gostaria que cada item da lista fosse ( infelizmente um humano falando em inglês e não português), mas você pode imaginar assim: Python, constrói uma lista pra mim onde cada item é uma tupla (chave, dict [chave]), onde cada chave esta no dict.

O dicionário é uma estrutura de dados muito importante pra resolver diversos problemas e te recomendo, caso não tenha feito ainda, um curso de estrutura de dados que ele com certeza vai abordar esse tema.

O motivo de eu transformar o dicionario numa lista é que cada estrutura de dados é melhor pra resolver certos tipos de problema. Enquanto que os dicionários são ótimos pra armazenar chaves e valores, listas são excelentes pra lidar com ordenação.

Sei que estou abusando, mas tem como eu formatar a saída dessa lista?

Ex: ('ID-789', 197) -> ID-789;197