12 de outubro de 2012

Criar um dicionário menor a partir de um maior

Você tem um dicionário com várias chaves, assim:
>>> grande = dict(nome='Joao',
...   idade=57,
...   naturalidade='Patos de Minas',
...   nacionalidade='Brasileira',
...   esposa='Maria',
...   filhos=['Pedrinho', 'Marquinhos'])
>>> print grande
{'naturalidade': 'Patos de Minas', 'idade': 57, 'filhos': ['Pedrinho', 'Marquinhos'],
'nome': 'Joao', 'esposa': 'Maria', 'nacionalidade': 'Brasileira'}

Agora, você quer criar um outro dicionário menor apenas com as chaves nome, idade e naturalidade, a partir do maior, que tem mais chaves. O normal seria fazer assim:
>>> menor = {}
>>> menor['nome'] = grande['nome']
>>> menor['idade'] = grande['idade']
>>> menor['naturalidade'] = grande['naturalidade']
>>> print menor
{'idade': 57, 'naturalidade': 'Patos de Minas', 'nome': 'Joao'}

O código acima funciona, mas que tal usarmos o poder do Python e digitarmos menos código? É possível percorrer o dicionário original e gerar um novo em um só passo, assim:
>>> outro = {chave: grande.get(chave) for chave in 'nome idade naturalidade'.split()}
>>> print outro
{'idade': 57, 'naturalidade': 'Patos de Minas', 'nome': 'Joao'}

Viu? O mesmo resultado.

Agora, vamos analisar o código.

Nós usamos um recurso chamado dict comprehension, indicado pelos símbolos { e } ao redor de todo o código à direita do sinal de igual. Ele é irmão da list comprehension e existe a partir do Python 2.7, junto com o set comprehension. Todos eles usam o mesmo raciocínio: percorrer um objeto iterável de modo simples, sem ter que criar um loop for de várias linhas.

Depois, criamos uma lista de chaves, com o comando split(). Cada nome, separado por um espaço em branco vira um item dessa lista dinâmica e temporária.

Para cada item dessa lista (chave), vamos pegar o conteúdo dela no dicionário grande e usá-lo para retornar o item para o dicionário outro.

Aqui, uma dica. Note que não indexamos o dicionário grande diretamente. Ao invés disso, usamos o método get(). Isso evita que o programa dê erro se as chaves que procuramos em grande não existirem.

Um bom uso para os dict comprehensions é quando você quer retornar uma lista de campos para seu template (ou view, no caso do Web2py). Ao invés de retornar locals() e deixar o programador que vai dar manutenção em seu código louco, use:
meu_locals = locals()
return {k:meu_locals.get(k) for k in 'nome idade naturalidade'.split()}

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.

Nenhum comentário:

Postar um comentário

Marcadores