Como usar dicionários ordenados no Python?
Ordenando um Dicionário em Python: Valores, Chaves e Mais
por Ian Currie data-structures intermediário
Neste tutorial, você irá:
- Revisar como usar a função
sorted()
- Aprender como obter visualizações do 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
- Revisar as compreensões de dicionário e o construtor
dict()
para reconstruir seus dicionários - Considerar estruturas de dados alternativas para seus dados de chave-valor
Ao longo do caminho, você também usará o módulo timeit
para cronometrar seu código e obter resultados concretos para comparar os diferentes métodos de ordenação de dados de chave-valor. Você também irá considerar se um dicionário ordenado é realmente a sua melhor opção, uma vez que não é um padrão particularmente comum.
Primeiro, você aprenderá alguns conhecimentos fundamentais antes de tentar ordenar um dicionário em Python.
Redescobrindo a Ordem de um Dicionário em Python
Se você quisesse manter um dicionário ordenado como uma estrutura de dados antes do Python 3.6, poderia usar a classe collections.OrderedDict
. Mas, desde o Python 3.7, os dicionários regulares preservam a ordem de inserção por padrão.
Primeiro, vamos criar um exemplo de um dicionário não ordenado para entender melhor a situação:
Saída:
Observe que o dicionário não está ordenado. A ordem dos pares de chave-valor não segue uma ordem específica.
Agora, vamos ver o comportamento padrão da função sorted()
ao ordenar um dicionário:
Saída:
Observe que a função sorted()
retorna apenas as chaves do dicionário em uma lista ordenada. Os valores associados às chaves são excluídos.
Se você deseja ordenar o dicionário com base nos valores em vez das chaves, você pode usar a função sorted()
com o parâmetro key
:
Saída:
Ainda assim, o resultado não é o que esperávamos. Vamos ver então como podemos ordenar um dicionário adequadamente.
Ordenando Dicionários em Python
A maneira mais comum de ordenar um dicionário em Python é usar a função sorted()
com o parâmetro key
, que especifica uma função de chave que será aplicada a cada elemento antes da comparação.
Usando a função sorted()
Para ordenar um dicionário com base nas chaves, você pode usar a função sorted()
diretamente no dicionário:
Saída:
Observe que somente as chaves são retornadas em uma lista ordenada.
Para ordenar um dicionário com base nos valores, você pode usar a função sorted()
com o parâmetro key
e a função my_dict.get
como argumento:
Saída:
Agora, as chaves são retornadas em uma lista ordenada com base nos valores associados a elas.
Se você quiser ordenar o dicionário com base nos itens (chave-valor), em vez de apenas nas chaves, você pode usar o método items()
para obter uma lista de tuplas dos itens do dicionário e, em seguida, usar a função sorted()
com o parâmetro key
para classificar as tuplas com base nos valores:
Saída:
Agora a lista de tuplas é retornada em uma ordem classificada com base nos valores.
Obtendo Chaves, Valores ou Ambos de um Dicionário
Além de ordenar um dicionário, também é comum precisar acessar apenas as chaves, apenas os valores ou ambos. Aqui estão algumas opções:
Para obter apenas as chaves de um dicionário, você pode usar o método keys()
:
Saída:
Para obter apenas os valores de um dicionário, você pode usar o método values()
:
Saída:
Para obter tanto as chaves quanto os valores de um dicionário, você pode usar o método items()
:
Saída:
Esses métodos retornam objetos de visualização, que são iteráveis e refletem as mudanças feitas no dicionário original. Isso significa que você pode iterar diretamente sobre as chaves, valores ou itens, ou convertê-los em outras estruturas de dados, como listas ou tuplas.
Entendendo Como o Python Ordena Tuplas
Quando você usa a função sorted()
para classificar um dicionário com o parâmetro key
e usa uma função (ou lambda function) para especificar a ordem de classificação, você pode encontrar situações em que precisa classificar com base em vários atributos de um valor. Para isso, é necessário entender como o Python ordena as tuplas.
O Python classifica as tuplas por comparação lexicográfica. Isso significa que, ao comparar duas tuplas, a primeira posição de cada tupla é comparada e, em caso de empate, a segunda posição é comparada, e assim por diante, até todas as posições serem comparadas ou a diferença ser encontrada.
Por exemplo, vamos supor que temos uma lista de tuplas com o seguinte formato: [(1, "abc"), (2, "xyz"), (2, "abc"), (3, "xyz")]
. Se usarmos a função sorted()
com o parâmetro key
para classificá-las, o código seria:
Saída:
Observe que as tuplas são classificadas primeiro pelo segundo elemento (string) e, em seguida, pelo primeiro elemento (inteiro).
Usando o Parâmetro key
e Funções Lambda
Para classificar um dicionário com base nos valores associados às chaves, em vez das próprias chaves, você pode usar uma função lambda como o parâmetro key
da função sorted()
. A função lambda recebe cada chave do dicionário como entrada e retorna o valor associado a essa chave. Esse valor será usado para classificar as chaves do dicionário.
Saída:
Aqui, a função lambda lambda x: my_dict[x]
é aplicada a cada chave x
do dicionário my_dict
. A função retorna o valor my_dict[x]
associado a cada chave x
. Em seguida, o sorted()
classifica as chaves do dicionário com base nesses valores.
Você também pode usar uma função lambda para classificar com base em múltiplos atributos. Por exemplo, se você tiver um dicionário contendo nomes associados a idades e quiser classificar primeiro pelo nome e, em caso de empate, pela idade, você pode usar a seguinte função lambda:
Saída:
A função lambda (x[0], x[1])
retorna uma tupla contendo o primeiro elemento x[0]
(nome) e o segundo elemento x[1]
(idade). As chaves do dicionário são então classificadas primeiro pelo nome e, em seguida, pela idade.
Selecionando um Valor Aninhado com uma Chave de Classificação
Em alguns casos, você pode ter um dicionário aninhado em que deseja classificar as chaves com base em um valor aninhado. Para fazer isso, você pode usar uma função lambda com várias chamadas ao método get()
para percorrer as chaves aninhadas até chegar ao valor desejado.
Saída:
Aqui, a função lambda lambda x: nested_dict[x].get("f")
é aplicada a cada chave x
do dicionário nested_dict
. A função obtém o valor aninhado correspondente à chave x
usando o método get()
. O sorted()
classifica as chaves do dicionário com base nesses valores aninhados.
Convertendo de Volta para um Dicionário
Depois de ordenar um dicionário, você pode querer reconstruí-lo como um novo dicionário com base na ordem classificada das chaves. Você pode fazer isso usando uma compreensão de dicionário ou o construtor dict()
.
Usando uma compreensão de dicionário, você pode iterar pela lista ordenada de chaves e criar um novo dicionário com base nas chaves e valores originais:
Saída:
Usando o construtor dict()
, você pode criar um novo dicionário passando uma lista de tuplas contendo as chaves e valores ordenados:
Saída:
Agora você tem um novo dicionário ordenado.
Considerando Questões Estratégicas e de Desempenho
Ao trabalhar com dicionários ordenados em Python, é importante considerar questões estratégicas e de desempenho. Aqui estão algumas considerações:
Usando Funções Getter Especiais para Aumentar o Desempenho e a Legibilidade
Quando você usa a função sorted()
em um dicionário grande, pode haver um custo considerável de desempenho para acessar os valores associados às chaves durante cada comparação de classificação. Para melhorar o desempenho, você pode pré-obter os valores do dicionário usando funções getter especiais.
Por exemplo, se você tiver um dicionário grande em que os valores associados às chaves sejam muito pequenos, você pode usar a função getter operator.itemgetter()
para obter os valores de uma só vez antes de ordenar o dicionário:
Saída:
Aqui, a função operator.itemgetter()
obtém os valores associados às chaves usando o método keys()
do dicionário. Os valores obtidos são armazenados na variável values
e usados para classificar as chaves do dicionário.
Medindo o Desempenho ao Usar o itemgetter()
Para medir o desempenho ao usar a função getter itemgetter()
, você pode usar o módulo timeit
. O módulo timeit
permite que você cronometre o tempo de execução de pequenas porções de código Python.
Aqui está um exemplo de como medir o desempenho ao classificar um dicionário com a função getter itemgetter()
:
Saída:
Aqui, o código é executado 1.000.000 de vezes e o tempo de execução é medido. Isso permite que você compare o desempenho de diferentes abordagens para ordenar um dicionário.
Decidindo Se Você Deseja Usar um Dicionário Ordenado
Embora seja possível ordenar um dicionário em Python, é importante considerar se essa é a melhor estrutura de dados para a tarefa que você está realizando. Dicionários ordenados podem ser úteis em determinadas situações em que a ordem dos pares de chave-valor é importante. No entanto, eles têm um custo adicional de desempenho e memória em comparação com dicionários não ordenados.
Se a ordem dos pares de chave-valor não for importante ou você precisar acessar os elementos de forma mais eficiente, pode ser melhor usar um dicionário não ordenado ou outra estrutura de dados, como uma lista de tuplas ou uma lista de dicionários.
Comparando o Desempenho de Diferentes Estruturas de Dados
Ao decidir qual estrutura de dados usar, é útil comparar o desempenho de diferentes estruturas para a sua tarefa específica. O módulo timeit
pode ser usado para comparar o desempenho de diferentes abordagens e escolher a mais eficiente.
Por exemplo, vamos comparar o desempenho de ordenar um dicionário usando sorted()
, reconstruir o dicionário usando diferentes abordagens e usar uma lista de tuplas em vez de um dicionário.
Saída:
Neste exemplo, comparamos o tempo de execução de diferentes abordagens para ordenar um dicionário com 10.000 elementos. Os tempos de execução são medidos em segundos.
Comparando o Desempenho da Ordenação
Além de comparar o desempenho das diferentes estruturas de dados, também é útil comparar o desempenho da ordenação em si. Em Python, a complexidade da ordenação é em média O(n log n), onde n é o número de elementos a serem ordenados. No entanto, o desempenho real pode variar dependendo dos detalhes de implementação.
Para comparar o desempenho da ordenação, você pode usar o módulo timeit
para medir o tempo de execução da função sorted()
em uma lista de valores em diferentes tamanhos.
Saída:
Neste exemplo, comparamos o tempo de execução da função sorted()
ao ordenar uma lista de diferentes tamanhos em ordem crescente e decrescente. Os tempos de execução são medidos em segundos.
Comparando o Desempenho das Consultas
Além do tempo de ordenação, também é útil comparar o desempenho das consultas a valores em diferentes estruturas de dados. Em Python, as consultas em dicionários são executadas em tempo médio O(1), ou seja, a complexidade é constante, independentemente do tamanho do dicionário.
Vamos comparar o tempo de consulta de um valor específico em um dicionário ordenado, um dicionário não ordenado e uma lista de tuplas usando a função timeit
:
Saída:
Neste exemplo, comparamos o tempo de consulta de um valor específico em um dicionário original, um dicionário ordenado e uma lista de tuplas. Os tempos de execução são medidos em segundos.
Conclusão
Neste tutorial, você aprendeu como ordenar um dicionário em Python usando a função sorted()
e o parâmetro key
. Você também viu como obter visualizações de chaves, valores ou ambos de um dicionário e como especificar uma chave de ordenação para classificar o dicionário por valor, chave ou atributo aninhado. Além disso, você aprendeu a reconstruir um dicionário a partir de uma lista ordenada de chaves e destacou considerações estratégicas e de desempenho ao trabalhar com dicionários ordenados.
Ao fazer tudo isso, você usou o módulo timeit
para medir o tempo de execução e comparar o desempenho de diferentes abordagens e estruturas de dados.
Lembre-se de considerar se um dicionário ordenado é realmente necessário para a sua tarefa e de comparar o desempenho e as características das diferentes estruturas de dados disponíveis antes de fazer sua escolha.
Espero que este tutorial tenha sido útil para você entender como ordenar dicionários em Python. Agora você poderá aplicar esse conhecimento em seus próprios projetos Python. Happy coding!