Pular para o conteúdo

Como ordenar um dicionário em Python pelo valor?

[

Ordenando um Dicionário em Python por Valor

Você possui um dicionário, mas gostaria de ordenar os pares chave-valor. Talvez você tenha tentado passar um dicionário para a função sorted(), mas não obteve os resultados esperados. Neste tutorial, vamos explorar tudo o que você precisa saber se quiser ordenar dicionários em Python.

Ao longo deste tutorial, você vai:

  • Rever como usar a função sorted();
  • Aprender como obter views de dicionários para iterar sobre eles;
  • Entender como os dicionários são convertidos em listas durante a ordenação;
  • Aprender como especificar uma chave de ordenação para ordenar um dicionário por valor, chave ou atributo aninhado;
  • Revisar as comprehensions de dicionário e o construtor dict() para reconstruir seus dicionários;
  • Considerar estruturas de dados alternativas para os seus dados chave-valor.

Ao longo do caminho, você também vai utilizar o módulo timeit para cronometrar seu código e obter resultados claros para comparar os diferentes métodos de ordenação de dados chave-valor. Também vai considerar se um dicionário ordenado é realmente a melhor opção, pois não é um padrão muito comum.

Para aproveitar ao máximo este tutorial, você deve saber sobre dicionários, listas, tuplas e funções em Python. Com esse conhecimento, você será capaz de ordenar dicionários até o final deste tutorial. Alguma exposição a funções de alta ordem, como funções lambda, também será útil, mas não é obrigatória.

Redescobrindo a Ordem dos Dicionários em Python

Se você desejava manter um dicionário ordenado como estrutura de dados antes do Python 3.6, você tinha que usar a classe collections.OrderedDict. A partir do Python 3.7, no entanto, o próprio dicionário nativo preserva a ordem de inserção.

Ordenando Dicionários em Python

Usando a Função sorted()

A primeira opção para ordenar um dicionário em Python é utilizar a função sorted(). A função sorted() recebe um iterável como argumento e retorna uma nova lista contendo os elementos do iterável ordenados. Para ordenar um dicionário, você precisa passar a função sorted() junto com o método items() do dicionário, que retorna uma lista de tuplas contendo os pares chave-valor.

players = {"Messi": 10, "Ronaldo": 7, "Neymar": 10, "Mbappe": 7}
sorted_players = sorted(players.items(), key=lambda x: x[1], reverse=True)
print(sorted_players)

No exemplo acima, temos um dicionário chamado players com os jogadores de futebol e as suas respectivas camisas. Utilizamos a função sorted() passando o método items() do dicionário players como argumento e especificamos uma função lambda como chave de ordenação. Essa função lambda retorna o segundo elemento (valor) de cada tupla, o que garante que os jogadores sejam ordenados pela quantidade de gols, em ordem decrescente.

Ao executar o código acima, você obterá a seguinte saída:

[('Messi', 10), ('Neymar', 10), ('Ronaldo', 7), ('Mbappe', 7)]

Você pode notar que os jogadores Messi e Neymar estão primeiro na lista, seguidos por Ronaldo e Mbappe. Isso ocorre porque eles têm mais gols do que os outros jogadores.

Obtendo Chaves, Valores ou Ambos de um Dicionário

Ao utilizar a função sorted() em um dicionário, você pode especificar se deseja ordenar pelas chaves, pelos valores ou por ambos. Para determinar o critério de ordenação, você precisa passar a função sorted() junto com o método apropriado do dicionário:

  • items(): retorna uma lista de tuplas (chave, valor) de um dicionário. Você pode utilizá-lo para ordenar pelo valor de cada par chave-valor.

  • keys(): retorna uma lista contendo as chaves de um dicionário. Você pode utilizá-lo para ordenar pelo valor das chaves.

  • values(): retorna uma lista contendo os valores de um dicionário. Você pode utilizá-lo para ordenar pelos valores.

Aqui está um exemplo para cada caso:

Ordenando pelo valor:

players = {"Messi": 10, "Ronaldo": 7, "Neymar": 10, "Mbappe": 7}
sorted_players = sorted(players.items(), key=lambda x: x[1], reverse=True)
print(sorted_players)

Ordenando pelas chaves:

players = {"Messi": 10, "Ronaldo": 7, "Neymar": 10, "Mbappe": 7}
sorted_players = sorted(players.keys())
print(sorted_players)

Ordenando pelos valores:

players = {"Messi": 10, "Ronaldo": 7, "Neymar": 10, "Mbappe": 7}
sorted_players = sorted(players.values())
print(sorted_players)

Entendendo Como o Python Ordena Tuplas

Quando você utiliza a função sorted() em um dicionário, é importante entender como o Python ordena as tuplas. O Python primeiro compara o primeiro elemento de cada tupla e, em seguida, o segundo elemento, o terceiro e assim por diante. Se houver empate, o Python comparará o próximo elemento até que todos os elementos tenham sido comparados ou até que haja uma diferença.

Por exemplo, se você tiver as seguintes tuplas:

tuplas = [(1, 2), (2, 1), (1, 1)]

A ordenação por padrão será feita comparando o primeiro elemento de cada tupla:

1, 2, 1

Como o primeiro elemento é o mesmo para a primeira e a terceira tuplas, o Python comparará o segundo elemento para decidir sua ordem:

2, 1, 1

Então, a tupla com o valor 2 no segundo elemento aparecerá primeiro.

Ao ordenar um dicionário, você precisa levar em consideração esse comportamento das tuplas. Especificar os elementos corretos da tupla na sua função chave é essencial para obter os resultados desejados.

Usando o Parâmetro key e Funções lambda

Em Python, você pode usar o parâmetro key da função sorted() para especificar uma função de chave de ordenação personalizada. Essa função será chamada para cada elemento do iterável e o valor retornado por ela será usado para ordenar os elementos.

Você pode criar uma função personalizada para definir as regras de ordenação ou utilizar uma função lambda, que é uma função anônima que pode ser criada em tempo de execução. Vamos ver um exemplo utilizando uma função lambda:

players = {"Messi": 10, "Ronaldo": 7, "Neymar": 10, "Mbappe": 7}
sorted_players = sorted(players.items(), key=lambda x: x[1], reverse=True)
print(sorted_players)

Nesse exemplo, utilizamos uma função lambda como chave de ordenação. Essa função recebe uma tupla (key, value) e retorna o segundo elemento, que é o valor. Passamos o parâmetro reverse=True para ordenar em ordem decrescente.

Selecionando um Valor Aninhado com uma Chave de Ordenação

Em alguns casos, você pode querer ordenar um dicionário por um valor aninhado em cada par chave-valor. Por exemplo, se seu dicionário contém informações sobre produtos, você pode querer ordená-lo pelo preço de cada produto, que está aninhado dentro de um dicionário.

Para selecionar um valor aninhado com uma chave de ordenação, você pode utilizar uma função lambda que percorra os níveis aninhados do dicionário. Vamos ver um exemplo:

products = {
"product1": {"name": "Television", "price": 500},
"product2": {"name": "Phone", "price": 1000},
"product3": {"name": "Tablet", "price": 700}
}
sorted_products = sorted(products.items(), key=lambda x: x[1]["price"])
print(sorted_products)

Nesse exemplo, temos um dicionário chamado products com informações sobre produtos. Utilizamos uma função lambda como chave de ordenação, passando a chave e o valor de cada par chave-valor. A função lambda utiliza o índice 1 para selecionar o valor, que é um dicionário com as informações do produto, e em seguida seleciona o valor da chave “price”. Isso garante que os produtos sejam ordenados pelo preço.

Convertendo de Volta para um Dicionário

Ao utilizar a função sorted() em um dicionário, o resultado será uma lista de tuplas contendo os pares chave-valor ordenados. Se você deseja converter esse resultado de volta para um dicionário, você pode utilizar uma dictionary comprehension ou o construtor dict(). Vamos ver um exemplo:

Utilizando dictionary comprehension:

players = {"Messi": 10, "Ronaldo": 7, "Neymar": 10, "Mbappe": 7}
sorted_players = sorted(players.items(), key=lambda x: x[1], reverse=True)
sorted_dict = {k: v for k, v in sorted_players}
print(sorted_dict)

Utilizando o construtor dict():

players = {"Messi": 10, "Ronaldo": 7, "Neymar": 10, "Mbappe": 7}
sorted_players = sorted(players.items(), key=lambda x: x[1], reverse=True)
sorted_dict = dict(sorted_players)
print(sorted_dict)

Ambos os exemplos produzirão a seguinte saída:

{'Messi': 10, 'Neymar': 10, 'Ronaldo': 7, 'Mbappe': 7}

Considerando Questões Estratégicas e de Desempenho

Ao trabalhar com dicionários e ordenação, é importante considerar algumas questões estratégicas e de desempenho para escolher a melhor abordagem para o seu caso específico.

Usando Funções Especiais de Obtenção para Aumentar o Desempenho e a Legibilidade

Em alguns casos, especialmente quando você precisa ordenar o dicionário várias vezes, é possível aumentar o desempenho e a legibilidade do código utilizando funções especiais de obtenção, como operator.itemgetter().

A função itemgetter() retorna uma função que pode ser usada como chave de ordenação e permite acessar o valor de um item em uma sequência, como uma lista ou uma tupla, de forma mais eficiente do que usando uma função lambda. Vamos ver um exemplo:

import operator
players = {"Messi": 10, "Ronaldo": 7, "Neymar": 10, "Mbappe": 7}
sorted_players = sorted(players.items(), key=operator.itemgetter(1), reverse=True)
print(sorted_players)

Nesse exemplo, utilizamos a função operator.itemgetter(1) como chave de ordenação para acessar o segundo item de cada tupla. Isso é mais eficiente e legível do que utilizar uma função lambda. O resultado será o mesmo que nos exemplos anteriores.

Medindo o Desempenho ao Usar itemgetter()

Se você estiver utilizando a função itemgetter() para aumentar o desempenho da ordenação, é importante medir o desempenho do seu código para garantir que a melhoria valha a pena. O módulo timeit permite medir o tempo de execução do seu código e comparar diferentes abordagens.

Aqui está um exemplo de como utilizar o módulo timeit para medir o desempenho da função itemgetter() em comparação com a função lambda:

import operator
import timeit
players = {"Messi": 10, "Ronaldo": 7, "Neymar": 10, "Mbappe": 7}
lambda_time = timeit.timeit(lambda: sorted(players.items(), key=lambda x: x[1], reverse=True))
itemgetter_time = timeit.timeit(lambda: sorted(players.items(), key=operator.itemgetter(1), reverse=True))
print("Tempo usando função lambda:", lambda_time)
print("Tempo usando itemgetter:", itemgetter_time)

Esse código cronometra o tempo de execução da função lambda e da função itemgetter() ao ordenar o dicionário players. Você pode comparar os resultados para verificar se a função itemgetter() realmente aumenta o desempenho do seu código.

Avaliando se Deseja Usar um Dicionário Ordenado

Embora a opção de ordenar um dicionário seja útil em alguns casos, nem sempre é a melhor opção em termos de desempenho e legibilidade do código. Se você precisa acessar os valores de um dicionário com frequência, é mais eficiente utilizar o próprio dicionário nativo do Python. Se você precisa ordenar os valores apenas para exibição ou para um processamento específico, pode ser mais eficiente utilizar uma estrutura de dados diferente, como uma lista de tuplas ou um objeto collections.OrderedDict.

A escolha entre um dicionário ordenado e uma estrutura de dados alternativa depende do seu caso de uso específico e das suas necessidades de desempenho.

Comparando o Desempenho de Diferentes Estruturas de Dados

Ao considerar a melhor abordagem para ordenar um dicionário, também é importante comparar o desempenho de diferentes estruturas de dados para o seu caso específico. Por exemplo, se você precisa ordenar o dicionário apenas uma vez e acessar os valores com frequência, pode ser mais eficiente converter o resultado para uma lista de tuplas e utilizar o método sort() da lista. No entanto, se você precisa ordenar o dicionário várias vezes e acessar os valores com frequência, pode valer a pena utilizar um dicionário ordenado.

Ao medir o desempenho das diferentes estruturas de dados, lembre-se de que o desempenho pode variar dependendo do tamanho do dicionário, da complexidade das chaves e dos valores, do número de operações de ordenação e da frequência das operações de acesso.

Comparando o Desempenho da Ordenação

Você também pode comparar o desempenho de diferentes métodos de ordenação para escolher o mais eficiente para o seu caso. Por exemplo, você pode comparar o desempenho dos métodos sorted(), list.sort() e operator.itemgetter() para ordenar um dicionário e escolher o mais adequado.

Ao medir o desempenho da ordenação, lembre-se de que o desempenho pode variar dependendo do tamanho do dicionário, da complexidade das chaves e dos valores e do número de elementos a serem ordenados.

Comparando o Desempenho das Pesquisas

Por fim, ao escolher a melhor abordagem para ordenar um dicionário, é importante considerar o desempenho das operações de pesquisa. Se você precisa acessar os valores do dicionário com frequência após a ordenação, certifique-se de que a estrutura de dados escolhida oferece um bom desempenho nas operações de pesquisa. Por exemplo, se você converter o dicionário para uma lista de tuplas, pode ser necessário percorrer toda a lista para encontrar um valor específico.

Conclusão

Ordenar um dicionário em Python pode ser feito utilizando a função sorted() em conjunto com o método apropriado do dicionário. É importante entender como as tuplas são ordenadas pelo Python e como selecionar um valor aninhado com uma chave de ordenação.

Além disso, é necessário considerar questões estratégicas e de desempenho ao escolher a melhor abordagem para ordenar um dicionário. Utilizar funções especiais de obtenção, medir o desempenho do código e considerar alternativas de estruturas de dados podem auxiliar na tomada de decisão.

Lembre-se de que a escolha entre um dicionário ordenado e uma estrutura de dados alternativa depende do seu caso de uso específico e das suas necessidades de desempenho e legibilidade do código.

Ao seguir as informações e os exemplos apresentados neste tutorial, você estará pronto para ordenar dicionários em Python de forma eficiente e assertiva.