Pular para o conteúdo

Como ordenar as chaves de um dicionário Python?

[

Ordenando um Dicionário em Python: Valores, Chaves e Mais

por Ian Currie 3 Comentários

Você tem 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 se quiser ordenar dicionários em Python.

Neste tutorial, você aprenderá:

  • Como usar a função sorted()
  • Como obter visões de dicionário para iterar
  • Como os dicionários são convertidos em listas durante a ordenação
  • Como especificar uma chave de ordenação para ordenar um dicionário por valor, chave ou atributo aninhado
  • Como usar compreensões de dicionário e o construtor dict() para reconstruir seus dicionários
  • Alternativas estruturas de dados 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 analisará se um dicionário ordenado é realmente a melhor opção, já que não é um padrão tão comum.

Para aproveitar ao máximo este tutorial, você deve estar familiarizado com dicionários, listas, tuplas e funções. Com esse conhecimento, você será capaz de ordenar dicionários ao final deste tutorial. Algum conhecimento sobre funções de ordem superior, como funções lambda, também será útil, mas não é obrigatório.

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

Redescobrindo a Ordem dos Dicionários em Python

Se você quisesse manter um dicionário ordenado como uma estrutura de dados, precisava usar uma estrutura de dados separada, como uma lista ou uma coleção OrderedDict. No entanto, desde o Python 3.7, você pode confiar na ordem de inserção em todos os dicionários Python.

A ordem de inserção é a ordem em que os pares chave-valor foram adicionados ao dicionário. Isso não significa necessariamente que os pares chave-valor serão ordenados alfabeticamente ou numericamente. A ordem de inserção é mantida para preservar a semântica da lógica de programação que depende da ordem em que os elementos foram adicionados.

Vamos continuar explorando o assunto com mais detalhes.

Compreendendo o que Significa Ordenar um Dicionário

Antes de começarmos a ordenar um dicionário, é importante entender o que realmente significa ordenar um dicionário. Em Python, um dicionário é uma coleção não ordenada de pares chave-valor.

Ao contrário das listas, em que os elementos são armazenados em uma sequência ordenada, os dicionários não têm uma ordem interna definida. Portanto, não faz sentido falar sobre “classificar” um dicionário em sua forma original.

No entanto, às vezes, pode ser útil obter uma versão ordenada dos pares chave-valor de um dicionário. Por exemplo, você pode querer percorrer um dicionário em uma determinada ordem, com base nos valores ou nas chaves. É aí que entra a função sorted().

Vamos ver como usar a função sorted() para ordenar um dicionário.

Usando a função sorted()

A função sorted() é uma função incorporada do Python que retorna uma nova lista contendo os elementos em uma sequência, em ordem crescente ou decrescente.

Para usar a função sorted() em um dicionário, você precisa fornecer uma sequência para ordenação. No caso de um dicionário, você pode usar a função items() para retornar uma sequência de pares chave-valor que pode ser ordenada.

Veja este exemplo de um dicionário não ordenado:

dicionario = {"banana": 3, "maçã": 1, "laranja": 2}

Se você quiser ordenar as chaves do dicionário em ordem alfabética, pode fazer o seguinte:

dicionario_ordenado = sorted(dicionario.items())

A variável dicionario_ordenado agora contém uma lista de pares chave-valor ordenados pelo valor das chaves, em ordem alfabética:

[('banana', 3), ('laranja', 2), ('maçã', 1)]

Observe que a função sorted() retorna uma nova lista contendo os elementos ordenados. O dicionário original não é modificado.

Agora que você sabe como usar a função sorted() em um dicionário, vamos explorar outras maneiras de ordenar dicionários em Python.

Obtendo Chaves, Valores ou Ambos de um Dicionário

Ao usar a função sorted(), você pode especificar qual parte dos pares chave-valor deseja ordenar: as chaves, os valores ou ambos.

A função items() que vimos anteriormente retorna uma sequência de pares chave-valor. Você pode usar as funções keys() e values(), respectivamente, se quiser obter apenas as chaves ou os valores de um dicionário.

Vamos ver como fazer isso:

dicionario = {"banana": 3, "maçã": 1, "laranja": 2}
# Ordenar as chaves em ordem alfabética
chaves_ordenadas = sorted(dicionario.keys())
print(chaves_ordenadas)
# Saída: ['banana', 'laranja', 'maçã']
# Ordenar os valores em ordem crescente
valores_ordenados = sorted(dicionario.values())
print(valores_ordenados)
# Saída: [1, 2, 3]
# Ordenar os pares chave-valor pelo valor das chaves em ordem alfabética
pares_ordenados = sorted(dicionario.items())
print(pares_ordenados)
# Saída: [('banana', 3), ('laranja', 2), ('maçã', 1)]

Observe que os valores são retornados como uma lista de valores, independentemente das chaves associadas a eles. Os pares chave-valor são retornados como uma lista de tuplas (chave, valor).

Agora que você sabe como obter chaves, valores ou ambos de um dicionário, vamos dar uma olhada em como o Python ordena tuplas.

Compreendendo como o Python Ordena Tuplas

Para ordenar um dicionário pelo valor de suas chaves, você precisa entender como o Python ordena tuplas.

Quando você usa a função sorted() em uma sequência de elementos, como uma lista ou uma tupla, o Python compara os elementos usando seus valores. Se dois elementos têm o mesmo valor, o Python compara os elementos de acordo com sua ordem na sequência original.

Por exemplo, se você tiver a seguinte lista:

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

E usar a função sorted() nessa lista, o Python ordenará os elementos com base no valor das tuplas, comparando os primeiros elementos primeiro e, em seguida, os segundos elementos:

lista_ordenada = sorted(lista)
print(lista_ordenada)
# Saída: [(1, 1), (1, 2), (2, 1), (2, 2)]

Observe que as tuplas foram ordenadas primeiro pelos primeiros elementos e, em seguida, pelos segundos elementos. Isso ocorre porque o Python compara os primeiros elementos das tuplas primeiro e, em seguida, os segundos elementos, se os primeiros elementos forem iguais.

Agora que você sabe como o Python ordena tuplas, vamos ver como usar o parâmetro key e funções lambda para especificar uma chave de ordenação personalizada.

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

O parâmetro key da função sorted() permite que você especifique uma função que será usada como chave de ordenação. Essa chave de ordenação determinará como o Python compara os elementos durante a ordenação.

Você pode usar uma função lambda como chave de ordenação para especificar uma função simples e personalizada.

Vamos ver um exemplo em que ordenamos um dicionário por valor, em ordem decrescente:

dicionario = {"banana": 3, "maçã": 1, "laranja": 2}
dicionario_ordenado = sorted(dicionario.items(), key=lambda x: x[1], reverse=True)
print(dicionario_ordenado)
# Saída: [('banana', 3), ('laranja', 2), ('maçã', 1)]

Neste exemplo, usamos uma função lambda para especificar x[1] como a chave de ordenação. Isso significa que estamos ordenando o dicionário com base nos valores (x[1]) dos pares chave-valor.

Observe também que definimos reverse=True, o que significa que queremos ordenar em ordem decrescente.

Agora você tem a capacidade de especificar uma chave de ordenação personalizada ao usar a função sorted() em um dicionário.

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

Em alguns casos, você pode ter um dicionário com valores aninhados, que são estruturas de dados complexas, como listas ou outros dicionários. Às vezes, você pode querer selecionar um valor aninhado específico como chave de ordenação.

Para fazer isso, podemos usar uma função lambda mais complexa, onde podemos extrair o valor aninhado desejado e usá-lo como chave de ordenação. Vamos ver um exemplo:

dicionario = {"banana": {"preço": 0.5}, "maçã": {"preço": 0.2}, "laranja": {"preço": 0.3}}
chave_aninhada = "preço"
dicionario_ordenado = sorted(dicionario.items(), key=lambda x: x[1][chave_aninhada])
print(dicionario_ordenado)
# Saída: [('maçã', {'preço': 0.2}), ('laranja', {'preço': 0.3}), ('banana', {'preço': 0.5})]

Neste exemplo, temos um dicionário em que os valores são outros dicionários aninhados. Usamos a função lambda para especificar x[1][chave_aninhada] como a chave de ordenação. Isso extrairá o valor aninhado com a chave especificada ("preço") e o usará para ordenar o dicionário.

Agora você sabe como selecionar um valor aninhado como chave de ordenação ao usar a função sorted() em um dicionário.

Convertendo de Volta para um Dicionário

Até agora, vimos como usar a função sorted() para ordenar um dicionário e obter uma lista de pares chave-valor ordenados. Mas e se você quiser voltar para o formato de dicionário original?

Você pode usar o construtor dict() para criar um novo dicionário a partir de uma lista de pares chave-valor ordenados.

Vamos ver um exemplo:

dicionario = {"banana": 3, "maçã": 1, "laranja": 2}
dicionario_ordenado = dict(sorted(dicionario.items()))
print(dicionario_ordenado)
# Saída: {'banana': 3, 'laranja': 2, 'maçã': 1}

Neste exemplo, usamos a função sorted() para obter uma lista de pares chave-valor ordenados. Em seguida, usamos o construtor dict() para criar um novo dicionário a partir dessa lista.

Observe que, ao converter a lista para um dicionário, a ordem de inserção original é perdida. Os pares chave-valor são armazenados em uma nova ordem, com base na ordem de classificação.

Agora você sabe como converter de volta para um dicionário a partir de pares chave-valor ordenados.

Considerando Questões Estratégicas e de Desempenho

A ordenação de um dicionário traz algumas considerações estratégicas e de desempenho. Antes de optar por usar um dicionário ordenado, é importante entender as implicações e comparar o desempenho com outras estruturas de dados.

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

Ao ordenar um dicionário, você pode usar funções getter especiais em vez de uma função lambda como chave de ordenação. Isso pode ajudar a aumentar o desempenho e a legibilidade do seu código.

Vamos ver um exemplo em que usamos a função itemgetter() do módulo operator para ordenar um dicionário pelo valor de suas chaves:

from operator import itemgetter
dicionario = {"banana": 3, "maçã": 1, "laranja": 2}
getter = itemgetter(1)
dicionario_ordenado = sorted(dicionario.items(), key=getter)
print(dicionario_ordenado)
# Saída: [('maçã', 1), ('laranja', 2), ('banana', 3)]

Neste exemplo, importamos a função itemgetter() do módulo operator. Em seguida, usamos itemgetter(1) para obter apenas o segundo elemento dos pares chave-valor retornados por items(). Em seguida, passamos essa função getter como chave de ordenação para a função sorted().

Usar funções getter especiais pode ajudar a tornar seu código mais legível e pode ter um desempenho ligeiramente melhor do que o uso de funções lambda.

Medindo o Desempenho ao Usar itemgetter()

Ao usar a função itemgetter() do módulo operator, você pode se perguntar se ela realmente melhora o desempenho em relação ao uso de funções lambda como chaves de ordenação.

Para medir o desempenho, você pode usar o módulo timeit do Python. Vamos ver como fazer isso:

from operator import itemgetter
from timeit import timeit
dicionario = {"banana": 3, "maçã": 1, "laranja": 2}
getter_lambda = lambda x: x[1]
getter_itemgetter = itemgetter(1)
tempo_lambda = timeit(lambda: sorted(dicionario.items(), key=getter_lambda), number=1000000)
tempo_itemgetter = timeit(lambda: sorted(dicionario.items(), key=getter_itemgetter), number=1000000)
print(f"Tempo com função lambda: {tempo_lambda} segundos")
print(f"Tempo com itemgetter: {tempo_itemgetter} segundos")

Neste exemplo, importamos a função itemgetter() do módulo operator e a função timeit do módulo timeit. Em seguida, definimos uma função lambda e uma função getter usando itemgetter(1).

Usamos a função timeit() para medir o tempo de execução das duas abordagens de ordenação. Executamos cada abordagem 1 milhão de vezes e imprimimos o tempo de execução em segundos.

Isso lhe dará uma ideia de como o uso de itemgetter() pode afetar o desempenho em relação ao uso de funções lambda.

Julgando se Você Deseja Usar um Dicionário Ordenado

Antes de decidir usar um dicionário ordenado, é importante considerar se essa é realmente a melhor opção para o seu caso de uso específico.

Embora os dicionários ordenados possam ser úteis em algumas situações, eles também têm algumas desvantagens em relação aos dicionários não ordenados.

As principais desvantagens dos dicionários ordenados são o maior consumo de memória e a menor velocidade de inserção e pesquisas. Se você precisa de uma estrutura de dados rápida e eficiente para acessar elementos por chave, um dicionário não ordenado pode ser uma opção melhor.

Considere cuidadosamente seus requisitos de desempenho e os padrões de acesso aos dados antes de decidir usar um dicionário ordenado.

Comparando o Desempenho de Diferentes Estruturas de Dados

Além de comparar o desempenho de diferentes abordagens de ordenação, você também pode comparar o desempenho de diferentes estruturas de dados para armazenar seus dados chave-valor.

Algumas alternativas ao uso de dicionários incluem listas de tuplas, listas de dicionários ou até mesmo outras estruturas de dados mais avançadas, como árvores de busca.

Ao medir o desempenho, leve em consideração o tempo de inserção, o tempo de pesquisa e o consumo de memória de cada estrutura de dados. Isso pode ajudá-lo a escolher a estrutura de dados mais adequada para o seu caso de uso.

Comparando o Desempenho da Ordenação

Além de comparar o desempenho de diferentes estruturas de dados, também é válido comparar o desempenho das diferentes abordagens de ordenação que vimos até agora.

Você pode usar o módulo timeit novamente para medir o tempo de execução de cada abordagem de ordenação.

from operator import itemgetter
from timeit import timeit
dicionario = {"banana": 3, "maçã": 1, "laranja": 2}
# Abordagem usando função lambda como chave de ordenação
tempo_lambda = timeit(lambda: sorted(dicionario.items(), key=lambda x: x[1]), number=1000000)
# Abordagem usando itemgetter como chave de ordenação
tempo_itemgetter = timeit(lambda: sorted(dicionario.items(), key=itemgetter(1)), number=1000000)
print(f"Tempo com função lambda: {tempo_lambda} segundos")
print(f"Tempo com itemgetter: {tempo_itemgetter} segundos")

Neste exemplo, usamos a função timeit() novamente para medir o tempo de execução de cada abordagem de ordenação. Executamos cada abordagem 1 milhão de vezes e imprimimos o tempo de execução em segundos.

Comparar o desempenho das diferentes abordagens de ordenação pode ajudá-lo a escolher a melhor abordagem para o seu caso de uso específico.

Comparando o Desempenho das Pesquisas

Além de medir o desempenho da ordenação, você também pode medir o desempenho das pesquisas em um dicionário ordenado versus um dicionário não ordenado.

Para medir o desempenho da pesquisa, você pode usar a função timeit() novamente para medir o tempo de execução de uma busca em cada dicionário.

from timeit import timeit
dicionario_ordenado = {"banana": 3, "laranja": 2, "maçã": 1}
def pesquisa(dicionario, chave):
return dicionario[chave]
tempo_busca_ordenada = timeit(lambda: pesquisa(dicionario_ordenado, "laranja"), number=1000000)
dicionario_nao_ordenado = {"maçã": 1, "banana": 3, "laranja": 2}
tempo_busca_nao_ordenada = timeit(lambda: pesquisa(dicionario_nao_ordenado, "laranja"), number=1000000)
print(f"Tempo de busca em um dicionário ordenado: {tempo_busca_ordenada} segundos")
print(f"Tempo de busca em um dicionário não ordenado: {tempo_busca_nao_ordenada} segundos")

Neste exemplo, usamos a função timeit() novamente para medir o tempo de execução de uma busca em cada dicionário. Executamos cada busca 1 milhão de vezes e imprimimos o tempo de execução em segundos.

Comparar o desempenho das pesquisas em um dicionário ordenado versus um dicionário não ordenado pode ajudá-lo a entender as diferenças de desempenho entre as duas abordagens.

Conclusão

Neste tutorial, você aprendeu como ordenar um dicionário em Python. Exploramos como usar a função sorted() para ordenar pares chave-valor em um dicionário. Também vimos como obter chaves, valores ou ambos de um dicionário e como o Python ordena tuplas.

Em seguida, você aprendeu a especificar uma chave de ordenação personalizada usando o parâmetro key e funções lambda. Além disso, vimos como selecionar um valor aninhado como chave de ordenação e como converter novamente para um dicionário a partir de pares chave-valor ordenados.

Discutimos considerações estratégicas e de desempenho ao ordenar um dicionário. Vimos como usar funções getter especiais para melhorar o desempenho e a legibilidade, como medir o desempenho ao usar itemgetter(), como julgar se um dicionário ordenado é o melhor ajuste para o seu caso de uso e como comparar o desempenho de diferentes estruturas de dados, ordenações e pesquisas.

Com o conhecimento adquirido neste tutorial, você poderá ordenar dicionários e escolher a melhor abordagem para seu caso específico.

Lembre-se de que, ao manipular grandes quantidades de dados ou processos críticos de desempenho, é importante realizar testes adicionais e considerar otimizações específicas para o seu caso de uso.