Eu quero fazer algo como:
foo = {'foo':1,'zip':2,'zam':3,'bar':4}
if ("foo","bar") in foo:
#do stuff
Como verifico se 'foo' e 'bar' estão no dict foo?
python
dictionary
Jean-François Corbett
fonte
fonte
set
é superior. Como de costume ... medi-lo!)Se você ainda está no Python 2, pode fazer
Se você ainda está em um Python realmente antigo <= 2.6, pode chamar
set
o dict, mas ele irá percorrer todo o dict para criar o conjunto, e isso é lento:fonte
set(("foo","bar")) <= myDict.keys()
que evita o conjunto temporário, por isso é muito mais rápido. Para os meus testes, é quase a mesma velocidade que usar todos quando a consulta tinha 10 itens. Porém, fica mais lento à medida que a consulta aumenta.if {'foo', 'bar'} <= set(myDict): ...
Equipamento de benchmarking simples para 3 das alternativas.
Coloque seus próprios valores para D e Q
fonte
d.viewkeys()
que fazerset(q) <= d.viewkeys()
.Python 2.7.5
temd.keys()
método também.set(q) <= ...
TypeError: can only compare to a set
. Desculpe! :))d.viewkeys() >= set(q)
. Eu vim aqui tentando descobrir por que o pedido é importante!Você não precisa envolver o lado esquerdo em um conjunto. Você pode fazer isso:
Isso também tem um desempenho melhor que a
all(k in d...)
solução.fonte
Usando conjuntos :
Alternativamente:
fonte
set(d)
é o mesmo queset(d.keys())
(sem a lista intermediária qued.keys()
construtos)Que tal agora:
fonte
all
.Eu acho que este é o mais inteligente e pithonic.
fonte
Embora eu goste da resposta de Alex Martelli, isso não me parece pitônico. Ou seja, eu pensei que uma parte importante de ser pitônico é ser facilmente compreensível. Com esse objetivo,
<=
não é fácil de entender.Embora haja mais caracteres, usar
issubset()
como sugerido pela resposta de Karl Voigtland é mais compreensível. Como esse método pode usar um dicionário como argumento, uma solução curta e compreensível é:Eu gostaria de usar
{'foo', 'bar'}
no lugar deset(('foo', 'bar'))
, porque é mais curto. No entanto, não é tão compreensível e acho que os aparelhos são muito facilmente confundidos como um dicionário.fonte
.issubset()
. Eu acho que estar na documentação do Python o torna Pythonic por padrão.A solução de Alex Martelli
set(queries) <= set(my_dict)
é o código mais curto, mas pode não ser o mais rápido. Suponha Q = len (consultas) e D = len (my_dict).Isso leva O (Q) + O (D) para fazer os dois conjuntos e, em seguida (espera-se!), Apenas O (min (Q, D)) para fazer o teste de subconjunto - assumindo, é claro, que o Python configurou a pesquisa é O (1) - este é o pior caso (quando a resposta for Verdadeira).
A solução geradora de hughdbrown (et al?)
all(k in my_dict for k in queries)
É o pior caso O (Q).Fatores complicadores:
(1) os loops no gadget baseado em conjunto são todos executados na velocidade C, enquanto o gadget baseado em qualquer loop é feito através do bytecode.
(2) O chamador do gadget baseado em qualquer um pode ser capaz de usar qualquer conhecimento de probabilidade de falha para solicitar os itens de consulta de acordo, enquanto o gadget baseado em conjunto não permite esse controle.
Como sempre, se a velocidade é importante, o benchmarking em condições operacionais é uma boa ideia.
fonte
Você pode usar .issubset () , bem
fonte
Que tal usar lambda?
fonte
Caso você queira:
então:
fonte
Não é para sugerir que isso não é algo em que você não tenha pensado, mas acho que a coisa mais simples é geralmente a melhor:
fonte
Jason, () não é necessário em Python.
fonte
Apenas minha opinião sobre isso, existem dois métodos que são fáceis de entender de todas as opções fornecidas. Portanto, meu principal critério é ter um código muito legível, não um código excepcionalmente rápido. Para manter o código compreensível, prefiro as seguintes possibilidades:
O fato de "var <= var2.keys ()" executar mais rápido nos meus testes abaixo, prefiro este.
fonte
No caso de determinar se apenas algumas chaves correspondem, isso funciona:
Ainda outra opção para descobrir se apenas algumas chaves correspondem:
fonte
Outra opção para detectar se todas as chaves estão em um ditado:
fonte
Isso parece funcionar
fonte
()
primeiro seria avaliado e resultariaTrue
, o qual verificaria seTrue in ok
. Como isso realmente funciona ?!