Se você realmente precisa modificar o dicionário original:
empty_keys = [k for k,v in metadata.iteritems() if not v]
for k in empty_keys:
del metadata[k]
Observe que temos que fazer uma lista das chaves vazias porque não podemos modificar um dicionário durante a iteração por ele (como você deve ter notado). Isso é menos caro (em termos de memória) do que criar um dicionário totalmente novo, a menos que haja muitas entradas com valores vazios.
Nneonneo
fonte
fonte
.iteritems()
por.items()
, o primeiro não funciona mais nas versões mais recentes do Python.Respostas:
A solução de BrenBarn é ideal (e pítônica, devo acrescentar). Aqui está outra solução (fp), no entanto:
fonte
Se você deseja uma abordagem completa, mas sucinta, para lidar com estruturas de dados do mundo real que geralmente estão aninhadas e podem até conter ciclos, recomendo olhar o utilitário de remapeamento do pacote de utilitários boltons .
Depois de
pip install boltons
copiar iterutils.py em seu projeto, basta fazer:Esta página tem muitos outros exemplos, incluindo aqueles que trabalham com objetos muito maiores da API do Github.
É puro Python, por isso funciona em qualquer lugar e é totalmente testado em Python 2.7 e 3.3+. O melhor de tudo é que eu o escrevi exatamente para casos como esse, então se você encontrar um caso que ele não resolve, você pode me bugar para consertá-lo aqui .
fonte
Com base na solução de Ryan , se você também tiver listas e dicionários aninhados:
Para Python 2:
Para Python 3:
fonte
d = { "things": [{ "name": "" }] }
Se você tiver um dicionário aninhado e quiser que funcione mesmo para subelementos vazios, pode usar uma variante recursiva da sugestão de BrenBarn:
fonte
items()
vez deiteritems()
para Python 3Resposta Rápida (TL; DR)
Exemplo01
Resposta Detalhada
Problema
Solução
Armadilhas
Exemplo alternativo
Exemplo 02
Veja também
fonte
Para python 3
fonte
Com base nas respostas de patriciasz e nneonneo e levando em consideração a possibilidade de que você queira excluir chaves que têm apenas certas coisas falsas (por exemplo
''
), mas não outras (por exemplo0
), ou talvez você até queira incluir algumas coisas verdadeiras (por exemplo'SPAM'
) , então você poderia fazer uma lista de ocorrências altamente específica:Infelizmente, isso não funciona muito bem, porque, por exemplo,
0 in unwanted
avalia paraTrue
. Precisamos discriminar entre0
outras coisas falsas, então temos que usaris
:... avalia para
False
.Agora use-o para
del
as coisas indesejadas:Se você quiser um novo dicionário, em vez de modificar
metadata
no local:fonte
[]
Eu li todas as respostas neste tópico e algumas também se referiram a este tópico: Remover dicts vazios no dicionário aninhado com função recursiva
Eu usei originalmente a solução aqui e funcionou muito bem:
Tentativa 1: Muito quente (sem desempenho ou à prova de futuro) :
Mas algumas questões de desempenho e compatibilidade foram levantadas no mundo Python 2.7:
isinstance
vez detype
for
loop para eficiênciaitems
vez deiteritems
Tentativa 2: Muito frio (falta memorização) :
DOH! Isso não é recursivo e nem um pouco memoizant.
Tentativa 3: na medida certa (até agora) :
fonte
Dictos misturados com matrizes
if isinstance(v, list):
, que limpa a lista usando ascrub_dict(d)
implementação original .fonte
Uma maneira alternativa de fazer isso é usar a compreensão do dicionário. Isso deve ser compatível com
2.7+
fonte
Aqui está uma opção se você estiver usando
pandas
:fonte
Alguns dos métodos mencionados acima ignoram se houver números inteiros e flutuam com valores 0 e 0,0
Se alguém quiser evitar o acima, pode usar o código abaixo (remove strings vazias e valores None do dicionário aninhado e da lista aninhada):
fonte
"Como também escrevo atualmente um aplicativo de desktop para meu trabalho com Python, encontrei um aplicativo de entrada de dados quando há muitas entradas e algumas não são obrigatórias, portanto o usuário pode deixá-lo em branco, para fins de validação, é fácil de pegar todas as entradas e, em seguida, descartar a chave ou valor vazio de um dicionário. Portanto, meu código acima mostra como podemos removê-los facilmente, usando a compreensão do dicionário e manter o elemento de valor do dicionário que não está em branco. Eu uso Python 3.8.3
fonte
Alguns benchmarking:
1. Lista de compreensão recriar dict
2. Recriação de compreensão de lista de dict usando dict ()
3. Faça um loop e exclua a chave se v for Nenhum
então loop e delete são os mais rápidos em 160ns, a compreensão da lista é metade mais lenta em ~ 375ns e com uma chamada para
dict()
é a metade mais lenta novamente em ~ 680ns.Envolver 3 em uma função o traz de volta para cerca de 275 ns. Além disso, para mim, o PyPy era duas vezes mais rápido do que o neet python.
fonte
list(dic.items())
py 3. Compreensão de dict, então? del ainda parece mais rápido para uma proporção baixa de valores nulos / vazios. Eu acho que construir essa lista é tão ruim para o consumo de memória do que apenas recriar o dicionário.