4 de dezembro de 2012

Como pegar a chave do item de maior valor em um dicionário


Ontem surgiu a seguinte pergunta na lista Python Brasil:
Pessoal, preciso pegar a chave do ítem do dicionário que tem o maior valor.
como faço isso ?

Algumas alternativas de solução apareceram, mas a mais rápida delas é a mais simples e não usa nenhuma construção complicada da linguagem. Sabemos que Python é uma linguagem poderosa e bem direta, mas muitas vezes esquecemos disso no dia-a-dia. Veja o código:
>>> d = {'a': 1000, 'b': 3000, 'c':100}
>>> print max(d, key=d.get)
b
>>> 

Só isso. Um comando, mas vários conceitos. Que tal entendermos como isso funciona? Por que a chave do dicionário é retornada, ao invés do maior valor?

A função max() aceita 2 argumentos: um iterável e uma função para gerar a chave de comparação, o argumento key=func.

Tá, mas o que é esse tal de iterável? Em poucas palavras, é um objeto que guarda uma sequência e pode ser percorrido: uma lista, um set, uma string, uma tupla, um dicionário. Como a pergunta feita trata de um dicionário, podemos resolver o problema usando esse conceito.

A forma mais simples de percorrer um iterável é usando o comando for:
>>> d = {'a': 1000, 'b': 3000, 'c':100}
>>> for cada in d:
>>>     print cada
a
c
b
>>> 

Veja que as chaves do dicionário foram mostradas, não os conteúdos delas. Guarde isso, porque essa característica é que vai fazer com que a solução do problema seja tão simples. Então, entendemos que ao percorrer um dicionário com for, as chaves é que são retornadas.

Se usássemos a função max(d) sem o argumento key=func, teríamos a chave 'c' como resposta, pois ela é a maior chave do dicionário. Mas queremos saber qual é chave com o maior conteúdo. Aí é que entra o tal argumento key=func.

Esse argumento recebe uma função. Cada item do iterável (as chaves, lembra?) será passado como argumento para essa função. Esse argumento key=func é poderosíssimo. Veja os exemplos desses posts, aqui mesmo no blog Aprenda Python:
  1. Ordenando e embaralhando uma lista
  2. Ordenando uma lista por mais de um campo

Então, na solução adotada para o problema, passamos max(d, key=d.get). Isso fará com que cada chave desse dicionário (um iterável) seja passada como argumento à função d.get(). Isso dirá à função max() que queremos que ela use o conteúdo de cada chave para saber qual é o maior, ao invés da chave em si.

Por isso temos o retorno da chave 'b', que é a que tem o maior conteúdo.

Leia a thread com as outras alternativas propostas.

Conheça mais sobre os conceitos de classificação em Python, lendo o Sorting Mini-HOW TO, na documentação oficial da linguagem. Principalmente a seção Key Functions.

Eu sou Vinicius Assef, um programador do século passado que gosta de Python, pratica Lean Development e acredita em Deus. Você pode me contactar por email ou twitter.

4 comentários:

  1. Puuutz, mas que sacada! Obrigado por mais essa pérola :D

    Por essas e outras o Vinícius Assef é um ninja do clan Ban.

    ResponderExcluir
  2. Muito legal a explicação detalhada. Valeu!

    ResponderExcluir
  3. Valeu pelo incentivo.

    Mas precisamos mesmo agradecer ao @tarantulae pela solução. :-)

    ResponderExcluir
  4. Parabés amigo, muito bom, já coloquei seu blog no favoritos!!

    ResponderExcluir

Marcadores