Sei que para remover uma entrada, 'chave' do meu dicionário d
, com segurança, você faz:
if d.has_key('key'):
del d['key']
No entanto, preciso remover várias entradas do dicionário com segurança. Eu estava pensando em definir as entradas em uma tupla, pois precisarei fazer isso mais de uma vez.
entitiesToREmove = ('a', 'b', 'c')
for x in entitiesToRemove:
if d.has_key(x):
del d[x]
No entanto, eu queria saber se existe uma maneira mais inteligente de fazer isso?
python
dictionary
dublintech
fonte
fonte
key in d
é mais do que Pythonicd.has_key(key)
stackoverflow.com/questions/1323410/has-key-or-infor x in set(d) & entities_to_remove: del d[x]
. Provavelmente isso só será mais eficiente seentities_to_remove
for "grande".Respostas:
Por que não assim:
Uma versão mais compacta foi fornecida por mattbornski usando dict.pop ()
fonte
del dict['key1'], dict['key2'], dict['key3']
for key in set(the_dict) & entries:
e ignorar okey in dict
teste.fonte
dict.pop()
elimina a necessidade de testes de existência importantes. Excelente..pop()
é ruim e antitônico, e preferiria a resposta aceita a essa.setdefault
. Se implementado corretamente (e tenho certeza de que é), ele faz apenas uma pesquisa no mapa de hash que é odict
, em vez de dois.Usando Compreensões de Dict
onde key1 e key2 devem ser removidos.
No exemplo abaixo, as teclas "b" e "c" devem ser removidas e mantidas em uma lista de chaves.
fonte
O(n)
. Toda a operação éO(mn)
, ondem
está o número de chaves no ditado en
o número de chaves na lista. Sugiro usar um conjunto{key1, key2}
, se possível.uma solução está usando
map
efilter
funcionapython 2
python 3
você obtém:
fonte
>>> d={"a":1,"b":2,"c":3} >>> l=("a","b","d") >>> map(d.__delitem__, filter(d.__contains__,l)) <map object at 0x10579b9e8> >>> print(d) {'a': 1, 'b': 2, 'c': 3}
list(map(d.__delitem__,filter(d.__contains__,l)))
.... em python função 3.4 mapa retornar um iteradordeque(map(...), maxlen=0)
para evitar criar uma lista de valores Nenhum; primeira importação comfrom collections import deque
Se você também precisar recuperar os valores para as chaves que está removendo, seria uma boa maneira de fazê-lo:
Obviamente, você ainda pode fazer isso apenas para a remoção das chaves
d
, mas criaria desnecessariamente a lista de valores com a compreensão da lista. Também é um pouco obscuro usar uma compreensão de lista apenas para o efeito colateral da função.fonte
valuesRemoved = dict((k, d.pop(k, None)) for k in entitiesToRemove)
e assim por diante.Encontrou uma solução com
pop
emap
A saída disso:
Eu respondi a essa pergunta tão tarde apenas porque acho que ajudará no futuro se alguém pesquisar a mesma. E isso pode ajudar.
Atualizar
O código acima gerará um erro se uma chave não existir no dict.
resultado:
fonte
keys
não existird
- você precisaria filtrá-la primeiro.Não tenho nenhum problema com nenhuma das respostas existentes, mas fiquei surpreso ao não encontrar esta solução:
Nota: Eu me deparei com essa pergunta vindo daqui . E minha resposta está relacionada a essa resposta .
fonte
Por que não:
Não sei o que você quer dizer com "maneira mais inteligente". Certamente existem outras maneiras, talvez com compreensão de dicionário:
fonte
na linha
fonte
Alguns testes de tempo para o cpython 3 mostram que um loop for simples é o caminho mais rápido e é bastante legível. A adição de uma função também não causa muita sobrecarga:
timeit resulta (10k iterações):
all(x.pop(v) for v in r) # 0.85
all(map(x.pop, r)) # 0.60
list(map(x.pop, r)) # 0.70
all(map(x.__delitem__, r)) # 0.44
del_all(x, r) # 0.40
<inline for loop>(x, r) # 0.35
Para pequenas iterações, fazer isso 'inline' era um pouco mais rápido, devido à sobrecarga da chamada de função. Mas
del_all
é seguro para fiapos, reutilizável e mais rápido do que todas as construções de compreensão e mapeamento de python.fonte
Eu acho que usar o fato de que as chaves podem ser tratadas como um conjunto é a melhor maneira se você estiver no python 3:
Exemplo:
fonte
Seria bom ter suporte completo para métodos definidos para dicionários (e não para a bagunça profana que estamos enfrentando no Python 3.9), para que você possa simplesmente "remover" um conjunto de chaves. No entanto, desde que não seja esse o caso, e você tenha um dicionário grande com um número potencialmente grande de chaves para remover, convém saber sobre o desempenho. Então, eu criei um código que cria algo grande o suficiente para comparações significativas: uma matriz de 100.000 x 1000, portanto, 10.000,00 itens no total.
10 milhões de itens ou mais não é incomum em algumas configurações. Comparando os dois métodos na minha máquina local, vejo uma ligeira melhora ao usar
map
epop
, presumivelmente por causa de menos chamadas de função, mas ambas demoram cerca de 2,5 segundos na minha máquina. Mas isso empalidece em comparação com o tempo necessário para criar o dicionário (55s), ou incluindo verificações dentro do loop. Se isso for provável, é melhor criar um conjunto que seja uma interseção das chaves do dicionário e do seu filtro:keys = cells.keys() & keys
Em resumo:
del
já está fortemente otimizado, portanto, não se preocupe em usá-lo.fonte
Estou atrasado para esta discussão, mas para qualquer outra pessoa. Uma solução pode ser criar uma lista de chaves como tal.
Em seguida, use pop () em uma lista de compreensão, ou for loop, para iterar sobre as teclas e pop uma de cada vez, como tal.
O 'n / a' está no caso de a chave não existir, um valor padrão precisa ser retornado.
fonte
new_dictionary
parece muito com uma lista;)