VIEW DICTIONARY ALPHABETICALLY - PYTHON

Asked

Viewed 66 times

0

I have a dictionary that has 2 keys (name, age), within each there is a list of values.

I need to put the names in alphabetical order and that the ages accompany the respective owners.

That’s the way I tried:

lista = ['pedro', 'joao', 'marcelo']
dicionario = {'nome': ['pedro', 'joao', 'marcelo'], 'idade': [9, 4, 5]}

lista.sort()
print(lista)

dicionario['nome'].sort()

for x in range(len(dicionario['nome'])):
    print(dicionario['nome'][x], dicionario['idade'][x])

2 answers

2

I think more important than the algorithm, you need to understand that the structure you chose for your data is not suitable. I’ll try to make a comparison here to see if it’s clear how much better:

You want to save information from several people, for this you have made a dictionary that contains lists with the information:

pessoas = {
    "nomes": ["Fulano", "Beltrano", "Sicrano"],
    "idades": [10, 20, 30],
}

If you were to represent this physically, you would have a book that contains only one person’s name per page and another book with only the ages on the pages. So to know the age of "Beltrano", you would have to open the book of names, find the page on which the name is and search the same page in the book of ages.

As you can see this is not practical. A more correct structure would be to have all the information you want from a person on the same page. In this example you would create a dictionary list instead of a list dictionary.

See the difference:

pessoas = [
    {"nome": "Fulano", "idade": 10},
    {"nome": "Beltrano", "idade": 20},
    {"nome": "Sicrano", "idade": 30},
]

That way, when you access pessoas[0] you’re seeing all that person’s information on a "page" only.


To sort the list of dictionaries just pass the parameter key for the function sorted to "teach" the function how to take the value by which you want to order.

pessoas_ordenado = sorted(pessoas, key=lambda obj: obj["nome"])

for pessoa in pessoas_ordenado:
    print(f"{pessoa['nome']} tem {pessoa['idade']} anos.")

Exit:

Beltrano tem 20 anos.
Fulano tem 10 anos.
Sicrano tem 30 anos.

Code running on Repl.it

The function sorted returns a new sorted list, if you do not need to save this separates list you can use the method list.sort() ordination inplace, that is, changes the original list.

Using list.sort() would look like this:

pessoas.sort(pessoas, key=lambda obj: obj["nome"])

for pessoa in pessoas:
    print(f"{pessoa['nome']} tem {pessoa['idade']} anos.")

I used dictionaries as an example to leave information of people in the same structure, but it could be any other structure as objects of a class Pessoa, tuples, named tuples, etc..

Some examples just for reference:

Classes:

class Pessoa:
    def __init__(self, nome, idade):
        self.nome = nome
        self.idade = idade

pessoas = [
    Pessoa(nome="Fulano", idade=10),
    Pessoa(nome="Beltrano", idade=20),
    Pessoa(nome="Sicrano", idade=30),
]

pessoas_ordenado = sorted(pessoas, key=lambda obj: obj.nome)

for pessoa in pessoas_ordenado:
    print(f"{pessoa.nome} tem {pessoa.idade} anos.")

Named tuples:

Pessoa = namedtuple('Pessoa', ['nome', 'idade'])

pessoas = [
    Pessoa(nome="Fulano", idade=10),
    Pessoa(nome="Beltrano", idade=20),
    Pessoa(nome="Sicrano", idade=30),
]

pessoas_ordenado = sorted(pessoas, key=lambda obj: obj.nome)

for pessoa in pessoas_ordenado:
    print(f"{pessoa.nome} tem {pessoa.idade} anos.")

0


Generally speaking, I think the most appropriate solution would be to create a class that encapsulates the two information in two attributes. That way they would always be together, and you wouldn’t need to have this added concern of always linking the actions of one list to another.

However, by answering what was asked, you can use the function zip in both lists. This function is a built-in function already in Python that aggregates the elements of different iterables. For example:

If the list1 has the elements [0,1,2,3,4], and Lista2 has ['a','b','c','d','e'] then the return of zip(lista1,lista2) will be [(0,'a'),(1,'b')...]

Applying in your case, we have:

#Mudei os nomes para uns mais simples (A,B,C)
dicionario = {'nome': ['Carolina', 'Ana', 'Beatriz'], 'idade': [1, 4, 5]}
print(dicionario)
# {'nome': ['Carolina', 'Ana', 'Beatriz'], 'idade': [1, 4, 5]}

#Atualizando a chave idade, baseado no que foi ordenado pela chave nome:
dicionario['idade'] = ([x for _, x in sorted(zip(dicionario['nome'], dicionario['idade']))])
print(dicionario)
#{'nome': ['Carolina', 'Ana', 'Beatriz'], 'idade': [4, 5, 1]}

#Por fim, atualizando a chave nome propriamente dita:
dicionario['nome'].sort()
print(dicionario)
#{'nome': ['Ana', 'Beatriz', 'Carolina'], 'idade': [4, 5, 1]}

That is, in general terms:

  • With the zip we associate the two lists: zip(dicionario['nome'], dicionario['idade'])
  • We order the result with: sorted(zip(...))
  • With list comprehension, we unpack only the age element after ordering: [x for _, x in listaDeTuplasOrdenadas]

For further reading, read here (in English).

  • Dude, it was right...very obg! I’ve been racking my brain for a while now.... vlw msm xD

  • @Henriquemarvinsouzadasilva You’re welcome! If the answer pleases you, don’t forget to accept it to help future site searches.

Browser other questions tagged

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