Eu queria testar se existe uma chave em um dicionário antes de atualizar o valor da chave. Eu escrevi o seguinte código:
if 'key1' in dict.keys():
print "blah"
else:
print "boo"
Eu acho que essa não é a melhor maneira de realizar essa tarefa. Existe uma maneira melhor de testar uma chave no dicionário?
python
dictionary
Mohan Gulati
fonte
fonte
dict.keys()
cria uma lista de chaves, de acordo com a documentação docs.python.org/2/library/stdtypes.html#dict.keys, mas eu ficaria surpreso se esse padrão não fosse otimizado para, em uma implementação séria, traduzir paraif 'key1' in dict:
.x in dict.keys()
para verificar as chaves. E isso aconteceu porque a maneira usual para iterar sobre as chaves em Java éfor (Type k : dict.keySet())
, este hábito causandofor k in dict.keys()
a se sentir mais natural do quefor k in dict
, mas depois as teclas verificação torna-se (que ainda deve ser muito bem em termos de desempenho?)if k in dict.keys()
também, que é um problema ...if k in dict_:
testa a presença de k nas CHAVES do dict_, portanto você ainda não precisadict_.keys()
. (Isto tem pouco me, como se lê para mim como seu teste para um valor em dict Mas não é..)Respostas:
in
é a maneira pretendida de testar a existência de uma chave em adict
.Se você queria um padrão, sempre pode usar
dict.get()
:e se você sempre quis garantir um valor padrão para qualquer chave, pode usar
dict.setdefault()
repetidamente oudefaultdict
nocollections
módulo, da seguinte maneira:mas, em geral, a
in
palavra-chave é a melhor maneira de fazer isso.fonte
get
se vou retirar o item do dicionário de qualquer maneira. Não faz sentido usarin
e puxar o item para fora do dicionário.in
é a melhor maneira de fazê-lo.0
por exemplo. Aprendi isso da maneira mais difícil: /Você não precisa chamar as teclas:
Isso será muito mais rápido , pois usa o hash do dicionário em vez de fazer uma pesquisa linear, o que as teclas de chamada fariam.
fonte
if key in d1
levou0.17265701293945312
segundos. A chamadaif key in d1.keys()
levou0.23871088027954102
- esta é a definição clássica de uma micro-otimização. Economizar0.07884883880615234
segundos não é um aumento de desempenho.keys()
fornece 0,01 segundo de benefício computacional. Para ~ 500.000 chaves, não ligarkeys()
oferece um benefício de 0,1 segundo. Para ~ 5.000.000 de chaves, a não chamadakeys()
é 0,4 segundos mais rápida, mas para 50.000.000 de chaves, CHAMARkeys()
É 3 SEGUNDOS MAIS RÁPIDO!Você pode testar a presença de uma chave em um dicionário usando a palavra-chave in :
Um uso comum para verificar a existência de uma chave em um dicionário antes de alterá-la é inicializar o valor por padrão (por exemplo, se seus valores são listas, por exemplo, e você deseja garantir que exista uma lista vazia à qual possa anexar ao inserir o primeiro valor para uma chave). Em casos como esses, você pode achar que o
collections.defaultdict()
tipo é do seu interesse.No código antigo, você também pode encontrar alguns usos de
has_key()
, um método obsoleto para verificar a existência de chaves nos dicionários (basta usarkey_name in dict_name
).fonte
key in dict.keys()
. Tente remover todo o código, exceto esta verificação, e veja qual é o seu resultado.Você pode encurtar isso:
No entanto, isso é, na melhor das hipóteses, uma melhoria cosmética. Por que você acredita que esse não é o melhor caminho?
fonte
Para informações adicionais sobre a velocidade de execução dos métodos propostos da resposta aceita (10m loops):
'key' in mydict
tempo decorrido 1,07 segmydict.get('key')
tempo decorrido 1,84 segmydefaultdict['key']
tempo decorrido 1,07 segPortanto, é recomendável usar
in
oudefaultdict
contraget
.fonte
get
's 1.84s é <1,07 * 2 ;-PEu recomendaria usar o
setdefault
método. Parece que fará tudo o que você quiser.fonte
setdefault
tem a ver com a pergunta do OP?O dicionário em python possui um método get ('key', padrão). Portanto, você pode apenas definir um valor padrão, caso não haja chave.
fonte
Que tal usar o EAFP (é mais fácil pedir perdão do que permissão):
Veja outras postagens do SO:
Usando try vs if em python ou
Verificando a existência de membros em Python
fonte
Usando operador ternário:
fonte
As maneiras pelas quais você pode obter os resultados são:
O que é melhor depende de três coisas:
Leia mais: http://paltman.com/try-except-performance-in-python-a-simple-test/
Uso de try / block em vez de 'in' ou 'if':
fonte
2to3
e vi que a sintaxe sem tentativa é sempre mais rápida que a sintaxe com tentativa, mesmo no caso em que a chave está no ditado.Somente Python 2: (e o python 2.7
in
já suporta )você pode usar o método has_key ():
fonte
.has_key()
foi descontinuado ; você deve usarin
como mostrado em outras respostas.Apenas um FYI adicionando a Chris. B (melhor resposta):
Funciona também; a razão é que a chamada
int()
retorna, o0
quedefaultdict
ocorre nos bastidores (ao construir um dicionário), daí o nome "Factory Function" na documentação.fonte
defaultdict(lambda: 0)
vez dedefaultdict(int)
porque acho mais claro o que está acontecendo; o leitor não precisa saber o que você recebe0
se ligarint()
sem argumentos. YMMV.Para ter uma idéia de como fazer isso, primeiro inspecionamos quais métodos podemos chamar no dicionário. Aqui estão os métodos:
O método brutal para verificar se a chave já existe pode ser o
get()
método:Os outros dois métodos interessantes
items()
ekeys()
parecem muito trabalho. Então, vamos examinar seget()
é o método certo para nós. Temos o nosso ditadod
:A impressão mostra a chave que não temos retornará
None
:Nós
podemusar isso para obter a informação se a chave está presente ou não. Mas considere isso se criarmos um ditado com um únicokey:None
:Liderar esse
get()
método não é confiável, caso alguns valores possam serNone
. Esta história deve ter um final mais feliz. Se usarmos oin
comparador:Nós obtemos os resultados corretos. Podemos examinar o código de bytes do Python:
Isso mostra que o
in
operador de comparação não é apenas mais confiável, mas ainda mais rápido queget()
.fonte
.get()
pode ter um segundo argumento paradefault
valor, que poderia ser usado para lidar com o problema em quekey:None
. exemplo:d.get("key", False)
.get()
é o caminho mais rápido. Outra opção é atribuir em um blocotry
/except
Dicionário Python tem o método chamado
__contains__
. Este método retornará True se o dicionário tiver a chave else retorna False.fonte
__contains__
diretamente. A maneira correta de fazer isso é usar oin
operador, que é ocontainment check
que chama a__contains__
função.foo = x['foo'] if x.__contains__('foo') else 'bar'
. Alguma idéia de como poderia usar oin
operador como parte dessa expressão?foo = x['foo'] if 'foo' in x else 'bar'
Compartilhando mais uma maneira de verificar se existe uma chave usando operadores booleanos.
Isso retorna
Explicação
Primeiro você deve saber que em Python,
0
,None
, ou objetos com comprimento zero avaliar aFalse
. Tudo o resto é avaliadoTrue
. As operações booleanas são avaliadas da esquerda para a direita e retornam o operando não True ou False.Vamos ver um exemplo:
Como
'Some string'
avalia paraTrue
, o restante door
não é avaliado e não há divisão por erro zero gerado.Mas se mudarmos, a ordem
1/0
é avaliada primeiro e gera uma exceção:Podemos usar isso como padrão para verificar se existe uma chave.
faz o mesmo que
Isso já retorna o resultado correto se a chave existir, mas queremos que ela imprima 'vaia' quando não existir. Então, pegamos o resultado e
or
ele com'boo'
fonte
Você pode usar
for
loop para iterar sobre o dicionário e obter o nome da chave que deseja encontrar no dicionário; depois disso, verifique se existe ou não usando aif
condição:fonte
it is exist
enot exist