how to take duplicates from a list of dictionaries

Asked

Viewed 54 times

3

i have that input . txt:

Brasil#ouro#futebol feminino
Argentina#bronze#basquete masculino
Brasil#prata#futebol masculino
Argentina#prata#tênis masculino
Brasil#prata#volei feminino
China#ouro#tênis de mesa masculino
Japão#ouro#judô feminino -50 kg

and I need to turn it into:

(1, 2, 0,'Brasil')
(1, 0, 0,'Japão')
(1, 0, 0,'China')
(0, 1, 1,'Argentina')

my code is like this:

lista = []

for linha in arquivo:
    n = linha.split("#")
    dados = {"pais": n[0], "ouro": 0, "prata": 0, "bronze": 0, "modalidade": n[2].rstrip("\n")}

    if n[1] == "ouro":
        dados["ouro"] = dados["ouro"] + 1
    elif n[1] == "prata":
        dados["prata"] = dados["prata"] + 1
    elif n[1] == "bronze":
        dados["bronze"] = dados["bronze"] + 1
    if dados["pais"] not in lista:
        lista.append(dados)


print(lista)

return None

and he returns this:

 [{'pais': 'Brasil', 'ouro': 1, 'prata': 0, 'bronze': 0, 'modalidade': 'futebol feminino'}, {'pais': 'Argentina', 'ouro': 0, 'prata': 0, 'bronze': 1, 'modalidade': 'basquete masculino'}, {'pais': 'Brasil', 'ouro': 0, 'prata': 1, 'bronze': 0, 'modalidade': 'futebol masculino'}, {'pais': 'Argentina', 'ouro': 0, 'prata': 1, 'bronze': 0, 'modalidade': 'tênis masculino'}, {'pais': 'Brasil', 'ouro': 0, 'prata': 1, 'bronze': 0, 'modalidade': 'volei feminino'}, {'pais': 'China', 'ouro': 1, 'prata': 0, 'bronze': 0, 'modalidade': 'tênis de mesa masculino'}, {'pais': 'Japão', 'ouro': 1, 'prata': 0, 'bronze': 0, 'modalidade': 'judô feminino -50 kg'}]

How do I add all the gold, silver and bronze medals(separately) of a country? ; how do I remove the duplicates of "fathers", but sum up the medals? Note: prohibited use of methods, import, etc. and I’m sorry for the stupidity, but I’m already trying on time and I’m flying.

2 answers

4


One way to solve it is to make the country’s name itself the key to the dictionary. And the value of this can be another dictionary containing the amount of medals.

Thus, it is possible to get the total, and then you convert this data to the list of tuples:

dados = {}
with open('entrada.txt') as arquivo:
    for linha in arquivo:
        pais, medalha, modalidade = linha.split('#')
        if pais not in dados: # país ainda não está no dicionário
            dados[pais] = {} # cria um dicionário de medalhas vazio
        dados[pais][medalha] = dados[pais].get(medalha, 0) + 1 # soma a quantidade de medalhas

# dicionário estará assim:
# {'Brasil': {'ouro': 1, 'prata': 2}, 'Argentina': {'bronze': 1, 'prata': 1}, 'China': {'ouro': 1}, 'Japão': {'ouro': 1}}
print(dados)

# cria a lista de tuplas
lista = []
for pais, medalhas in dados.items():
    lista.append((medalhas.get('ouro', 0), medalhas.get('prata', 0), medalhas.get('bronze', 0), pais))

print(lista) # [(1, 2, 0, 'Brasil'), (0, 1, 1, 'Argentina'), (1, 0, 0, 'China'), (1, 0, 0, 'Japão')]

The idea is that the dictionary dados stay that way:

{
    'Brasil':
    {
        'ouro': 1,
        'prata': 2
    },
    'Argentina':
    {
        'bronze': 1,
        'prata': 1
    },
    'China':
    {
        'ouro': 1
    },
    'Japão':
    {
        'ouro': 1
    }
}

That is, each country name points to another dictionary, containing the amount of medals.

With this, just scroll through this dictionary and create the list of tuples. When using get('ouro', 0), it returns zero if the medal does not exist in the respective dictionary.

  • Thank you very much!

1

Another possibility is to abandon the use of tuples, to tally medals, and in their place to use lists because tuples are immutable and not lists, which makes it easier to create a medal totaliser in a single-pass algorithm for each data item.

To facilitate totalization in a single-pass algorithm create a list with the total of medals each country and one dictionary as an index for each of the values entered in the totals list, where the key is the name of the country and the value is a reference for a medal totaliser entered in the list total.

total = []   #Lista contendo o total de medalhas de cada país.
paises = {}  #Dicionário de indices para cada país listado em total.

with open('medalhas.txt') as arquivo:
  #Para cada linha no arquivo 'medalhas.txt'...
  for linha in arquivo:
    pais, medalha, modalidade = linha.split('#')    #Separa em seus componente.
    i = 0 if medalha == "ouro" else 1 if medalha == "prata" else 2 #Calcula o índice da medalha.
    #Se o pais em questão ainda não foi indexado...
    if pais not in paises:
      resultado = [0, 0, 0, pais]   #Inicializa um novo totalizador de medalhas.
      resultado[i] = 1              #Contabiliza a primeira medalha.
      total.append(resultado)       #Popula a lista total com o novo totalizador.
      paises[pais] = resultado      #Cria um índice para o novo totalizador.
    else:
      paises[pais][i] = paises[pais][i] + 1         #Atualiza o total de medalhas.

Resulting in:

>>>print(total)
[[1, 2, 0, 'Brasil'], 
 [0, 1, 1, 'Argentina'], 
 [1, 0, 0, 'China'], 
 [1, 0, 0, 'Japão']]

Test the code on Repl.it

Browser other questions tagged

You are not signed in. Login or sign up in order to post.