Pular para o conteúdo

Como Classificar um Dicionário Python por Chave

[

Ordenando um Dicionário em Python por Chave

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, você aprenderá tudo o que precisa saber para ordenar dicionários em Python.

Neste tutorial, você irá:

  • Rever como usar a função sorted()
  • Aprender como obter visualizações de um dicionário para iterar
  • 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
  • Rever as compreensões de dicionário e o construtor dict() para reconstruir seus dicionários
  • Considerar estruturas de dados alternativas para seus dados chave-valor

Ao longo do caminho, você também usará o módulo timeit para medir o tempo de execução do seu código e obter resultados tangíveis para comparar os diferentes métodos de ordenação de dados chave-valor. Você também considerará se um dicionário ordenado é realmente a melhor opção, pois não é um padrão muito comum.

Primeiro, você aprenderá alguns conhecimentos fundamentais antes de tentar ordenar um dicionário em Python.

Descobrindo a Ordem do Dicionário em Python

Se você desejava manter um dicionário ordenado como uma estrutura de dados antes do Python 3.6, precisava usar a classe collections.OrderedDict. No entanto, com as alterações nas versões mais recentes do Python, a ordenação de um dicionário se tornou mais direta.

Entendendo o Que Significa Ordenar um Dicionário

Antes de mergulhar nas diferentes formas de ordenação de dicionários em Python, é importante entender o que realmente significa ordenar um dicionário. Diferente de outros tipos de dados, como listas, onde a ordenação envolve a troca de posições dos elementos, a ordenação de um dicionário envolve a reorganização dos pares chave-valor com base em determinados critérios.

Para ilustrar isso, considere o seguinte dicionário:

dicionario = {"c": 3, "a": 1, "b": 2}

Se você ordenar esse dicionário por chave, o resultado será:

{"a": 1, "b": 2, "c": 3}

Note que os pares chave-valor permanecem os mesmos, mas a ordem das chaves agora está em ordem alfabética.

Por outro lado, se você quiser ordenar o dicionário por valor, o resultado será:

{"a": 1, "b": 2, "c": 3}

Novamente, os pares chave-valor permanecem os mesmos, mas agora estão ordenados com base nos valores associados às chaves.

Agora que você entende o conceito por trás da ordenação de um dicionário, vamos ver como realizar esse processo em Python.

Ordenando Dicionários em Python

Existem várias maneiras de ordenar um dicionário em Python. Nesta seção, veremos diferentes abordagens que você pode usar, dependendo do resultado desejado.

Usando a Função sorted()

Uma das maneiras mais simples de ordenar um dicionário em Python é usando a função sorted(). Essa função retorna uma nova lista contendo as chaves do dicionário em uma ordem específica.

Veja um exemplo de como usar a função sorted() para ordenar um dicionário por chave:

dicionario = {"c": 3, "a": 1, "b": 2}
chaves_ordenadas = sorted(dicionario.keys())

Neste exemplo, a variável chaves_ordenadas conterá a lista [a, b, c], que são as chaves do dicionário dicionario em ordem alfabética.

Da mesma forma, você pode usar a função sorted() para ordenar um dicionário por valor:

dicionario = {"c": 3, "a": 1, "b": 2}
valores_ordenados = sorted(dicionario.values())

Neste caso, a variável valores_ordenados conterá a lista [1, 2, 3], que são os valores associados às chaves do dicionário dicionario em ordem crescente.

No entanto, é importante destacar que a função sorted() retorna uma lista de chaves ou valores do dicionário, não o próprio dicionário ordenado. Se você deseja obter um dicionário ordenado com base nas chaves ou valores, precisará usar abordagens diferentes, como veremos nos próximos tópicos.

Obtendo Chaves, Valores ou Ambos de um Dicionário

Você também pode usar os métodos keys(), values() e items() de um dicionário para obter as chaves, valores ou ambos em uma forma iterável. Esses métodos retornam objetos que podem ser facilmente ordenados usando a função sorted().

Veja um exemplo de como obter as chaves de um dicionário em ordem alfabética:

dicionario = {"c": 3, "a": 1, "b": 2}
chaves_ordenadas = sorted(dicionario.keys())

Neste caso, chaves_ordenadas será igual a ['a', 'b', 'c'].

Da mesma forma, você pode obter os valores do dicionário em ordem crescente:

dicionario = {"c": 3, "a": 1, "b": 2}
valores_ordenados = sorted(dicionario.values())

Neste caso, valores_ordenados será igual a [1, 2, 3].

Se você deseja obter uma lista de pares chave-valor ordenados por chave ou valor, pode usar o método items() em conjunto com a função sorted():

dicionario = {"c": 3, "a": 1, "b": 2}
pares_ordenados_por_chave = sorted(dicionario.items())
pares_ordenados_por_valor = sorted(dicionario.items(), key=lambda x: x[1])

No primeiro exemplo, pares_ordenados_por_chave será igual a [(a, 1), (b, 2), (c, 3)], onde os pares chave-valor estão ordenados por chave. No segundo exemplo, pares_ordenados_por_valor será igual a [(a, 1), (b, 2), (c, 3)], onde os pares chave-valor estão ordenados por valor.

Essa abordagem é útil quando você precisa fazer uma iteração ordenada sobre as chaves, valores ou pares chave-valor de um dicionário.

Entendendo Como Python Ordena Tuplas

Ao usar a função sorted() ou o método items() para ordenar um dicionário, é importante entender como Python ordena tuplas. Quando você passa uma lista de tuplas para a função sorted() ou o método items(), Python usa uma ordem lexicográfica para ordenar as tuplas.

A ordem lexicográfica significa que as tuplas são ordenadas com base no valor do primeiro elemento, e em caso de empate, com base no valor do segundo elemento e assim por diante.

Veja um exemplo para ilustrar isso. Considere a seguinte lista de tuplas:

lista_tuplas = [("b", 2), ("a", 2), ("c", 1)]

Se você usar a função sorted() com essa lista, os resultados serão:

sorted(lista_tuplas) # [(a, 2), (b, 2), (c, 1)]

Observe que o primeiro critério de ordenação é o valor do primeiro elemento da tupla. Como as tuplas ("b", 2) e ("a", 2) têm o mesmo primeiro elemento, elas são ordenadas com base no valor do segundo elemento, que é 2. A tupla ("c", 1) tem o menor valor do primeiro elemento, então ela fica em terceiro lugar.

Essa lógica de ordenação também se aplica quando você usa o método items() em um dicionário para obter pares chave-valor. Python primeiro ordenará com base nos valores das chaves e, em caso de empate, ordenará com base nos valores associados às chaves.

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

Você também pode usar o parâmetro key da função sorted() para especificar uma função de ordenação personalizada. Essa função é aplicada a cada elemento da sequência a ser ordenada e retorna um valor usado para realizar a ordenação.

Veja um exemplo de como usar o parâmetro key para ordenar um dicionário pelo valor associado às chaves:

dicionario = {"c": 3, "a": 1, "b": 2}
dicionario_ordenado_por_valor = sorted(dicionario.items(), key=lambda x: x[1])

Neste exemplo, a função lambda lambda x: x[1] é usada como o parâmetro key. Essa função recebe cada par chave-valor do dicionário e retorna o valor associado à chave. Dessa forma, a ordenação ocorre com base nos valores dos pares chave-valor.

O resultado será:

[("a", 1), ("b", 2), ("c", 3)]

Agora, os pares chave-valor estão ordenados com base nos valores associados às chaves.

Essa abordagem é útil quando você deseja realizar ordenações mais complexas, como ordenar por atributos aninhados em objetos ou por critérios diferentes dos padrões, como ordenar em ordem decrescente.

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

Além de ordenar dicionários por chave ou valor, você também pode usar uma chave de ordenação para selecionar um valor aninhado em um dicionário e fazer a ordenação com base nesse valor.

Veja um exemplo de como fazer isso usando a função sorted() e uma chave de ordenação personalizada:

dicionario = {"a": {"valor": 2}, "b": {"valor": 1}, "c": {"valor": 3}}
dicionario_ordenado_por_valor_aninhado = sorted(dicionario.items(), key=lambda x: x[1]["valor"])

Neste exemplo, a função lambda lambda x: x[1]["valor"] é usada como chave de ordenação. Essa função recebe cada par chave-valor do dicionário e retorna o valor aninhado associado à chave. Dessa forma, a ordenação ocorre com base nos valores aninhados dos pares chave-valor.

O resultado será:

[("b", {"valor": 1}), ("a", {"valor": 2}), ("c", {"valor": 3})]

Agora, os pares chave-valor estão ordenados com base nos valores aninhados {"valor": 1}, {"valor": 2} e {"valor": 3}.

Essa abordagem é útil quando você precisa ordenar um dicionário com base em um atributo específico aninhado em cada valor.

Convertendo de Volta para um Dicionário

Depois de ordenar um dicionário, você pode usar a função dict() e compreensões de dicionário para convertê-lo de volta para um dicionário. Essa abordagem é útil quando você deseja obter um dicionário ordenado com base nos resultados de uma ordenação.

Veja um exemplo de como converter uma lista ordenada de pares chave-valor de volta para um dicionário:

pares_ordenados_por_chave = [("a", 1), ("b", 2), ("c", 3)]
dicionario_ordenado_por_chave = dict(pares_ordenados_por_chave)

Neste exemplo, a função dict() é usada para converter a lista pares_ordenados_por_chave em um dicionário. O resultado será:

{"a": 1, "b": 2, "c": 3}

Agora, você tem um dicionário ordenado por chave novamente.

Da mesma forma, você pode usar compreensões de dicionário e a função dict() para converter uma lista de tuplas ordenadas por valor de volta para um dicionário:

pares_ordenados_por_valor = [("a", 1), ("b", 2), ("c", 3)]
dicionario_ordenado_por_valor = dict((chave, valor) for chave, valor in pares_ordenados_por_valor)

Neste exemplo, a lista pares_ordenados_por_valor é convertida para um dicionário usando uma compreensão de dicionário. O resultado será:

{"a": 1, "b": 2, "c": 3}

Agora, você tem um dicionário ordenado por valor novamente.

Essa abordagem é útil quando você precisa converter uma lista de pares chave-valor ordenados de volta para um dicionário.

Considerando Questões Estratégicas e de Desempenho

Ao ordenar um dicionário em Python, é importante considerar questões estratégicas e de desempenho para escolher a abordagem correta. Existem diferentes fatores a serem considerados, como a complexidade do código, a legibilidade, o tempo de execução e o uso de memória.

Usando Funções Getter Especiais para Aumentar o Desempenho e a Legibilidade

Quando você precisa ordenar um dicionário por valor, uma alternativa ao uso da função sorted() é usar funções getter especiais, como itemgetter(), para melhorar o desempenho e a legibilidade do código.

itemgetter() é uma função da biblioteca padrão do Python que permite extrair valores de uma sequência usando índices ou chaves. Nesse caso, você pode usá-la para extrair valores dos pares chave-valor de um dicionário.

Veja um exemplo de como usar itemgetter() para ordenar um dicionário por valor:

from operator import itemgetter
dicionario = {"c": 3, "a": 1, "b": 2}
dicionario_ordenado_por_valor = sorted(dicionario.items(), key=itemgetter(1))

Neste exemplo, a função itemgetter(1) é passada como chave de ordenação para sorted(). Isso faz com que a função itemgetter() extraia o valor associado a cada par chave-valor do dicionário. Dessa forma, a ordenação ocorre com base nos valores extraídos.

O resultado será:

[("a", 1), ("b", 2), ("c", 3)]

Essa abordagem pode ser mais eficiente em termos de desempenho, especialmente ao lidar com grandes quantidades de dados. Além disso, o código se torna mais legível, pois a função itemgetter() identifica claramente a intenção de ordenar pelo valor dos pares chave-valor.

Medindo o Desempenho ao Usar itemgetter()

Ao usar a função itemgetter() para ordenar um dicionário, é importante medir o desempenho do código para ter uma compreensão realista dos tempos de execução.

Você pode usar o módulo timeit para medir o tempo de execução do seu código e comparar diferentes abordagens de ordenação. Esse módulo permite que você execute código repetidamente e calcule o tempo médio de execução.

Veja um exemplo de como usar o módulo timeit para medir o tempo de execução de ordenações com itemgetter():

from operator import itemgetter
import timeit
dicionario = {"c": 3, "a": 1, "b": 2}
tempo_ordenacao = timeit.timeit(lambda: sorted(dicionario.items(), key=itemgetter(1)), number=100000)
print(f"Tempo de ordenação com itemgetter(): {tempo_ordenacao} segundos")

Neste exemplo, a função timeit.timeit() é usada para medir o tempo de execução da ordenação com itemgetter(). O parâmetro number define o número de vezes que o código será executado. O resultado será o tempo médio de execução em segundos.

Essa medição de desempenho ajuda você a ter uma noção clara das diferenças de tempo de execução entre abordagens e a escolher a mais adequada para suas necessidades.

Avaliando se Você Deseja Usar um Dicionário Ordenado

Embora a ordenação de um dicionário em Python seja possível, é importante avaliar se essa é realmente a melhor opção para o seu caso de uso. A ordenação de um dicionário envolve tempo de execução adicional e pode ser um processo desnecessário dependendo das operações que você realiza com os dados.

Considere cuidadosamente se você realmente precisa de um dicionário ordenado ou se pode trabalhar com o dicionário desordenado original. A ordem das chaves em um dicionário pode não ser relevante para o seu caso de uso e, nesse caso, ordenar o dicionário pode ser uma etapa desnecessária e potencialmente custosa em termos de desempenho.

Pense nas operações que você realizará com os dados do dicionário e se a ordem dos elementos é realmente importante. Em muitos casos, outras estruturas de dados, como listas ou conjuntos, podem ser mais adequadas para atender às suas necessidades.

Comparando o Desempenho de Estruturas de Dados Diferentes

Além de considerar o desempenho da ordenação em si, é importante comparar o desempenho geral de diferentes estruturas de dados ao lidar com dados chave-valor.

Por exemplo, se você precisa realizar várias operações de inserção, remoção e pesquisa de elementos em um grande conjunto de dados chave-valor, uma árvore de busca binária balanceada, como a implementada pelo módulo collections.OrderedDict, pode ser uma escolha mais eficiente.

Da mesma forma, se você precisa apenas iterar sobre os elementos em ordem específica, como um acesso sequencial ou uma iteração ordenada sobre as chaves, uma lista ordenada ou uma lista de tuplas pode ser mais adequada.

Portanto, é importante considerar o contexto completo e as operações que você realizará com os dados antes de decidir pelo uso de um dicionário ordenado.

Comparando o Desempenho da Ordenação

Se você está interessado em comparar o desempenho específico da ordenação de um dicionário em Python, pode usar o módulo timeit para medir o tempo de execução e fazer comparações diretas.

Veja um exemplo de como comparar o desempenho da ordenação de um dicionário usando diferentes abordagens:

from operator import itemgetter
import timeit
dicionario = {"c": 3, "a": 1, "b": 2}
tempo_ordenacao_sorted = timeit.timeit(lambda: sorted(dicionario.items(), key=itemgetter(1)), number=100000)
tempo_ordenacao_ordered_dict = timeit.timeit(lambda: dict(sorted(dicionario.items(), key=itemgetter(1)))), number=100000)
print(f"Tempo de ordenação com sorted(): {tempo_ordenacao_sorted} segundos")
print(f"Tempo de ordenação com OrderedDict: {tempo_ordenacao_ordered_dict} segundos")

Neste exemplo, medimos o tempo de execução da ordem de um dicionário usando a função sorted() e a classe collections.OrderedDict. O parâmetro number no timeit.timeit() define o número de vezes que cada abordagem é executada para obtermos o tempo médio de execução.

Com essa medição de desempenho, você pode comparar diretamente o tempo de execução das diferentes abordagens de ordenação e fazer uma escolha informada com base nas suas necessidades específicas.

Conclusão

Agora você tem todas as informações necessárias para ordenar um dicionário em Python. Você aprendeu as diferentes abordagens, desde o uso da função sorted() até o uso de funções getter especiais e a conversão de volta para um dicionário.

Lembre-se de considerar questões como desempenho, legibilidade e necessidade real de ordenação ao decidir utilizar um dicionário ordenado. Em muitos casos, outras estruturas de dados podem ser mais adequadas para atender às suas necessidades.

Experimente diferentes abordagens e faça medições de desempenho para encontrar a solução que melhor se adapta ao seu caso de uso. Com essas habilidades, você estará preparado para lidar com a ordenação de dicionários em Python de maneira eficiente e eficaz.