Existe alguma maneira simples de encontrar uma chave sabendo o valor em um dicionário?
Só consigo pensar no seguinte:
key = [key for key, value in dict_obj.items() if value == 'value'][0]
python
dictionary
RadiantHex
fonte
fonte
iteritems
como para mim isso faz uma diferença 40 vezes mais rápida ... usando o método () .nextreverse_dictionary = {v:k for k,v in dictionary.items()}
Respostas:
Não há nenhum. Não se esqueça de que o valor pode ser encontrado em qualquer número de chaves, incluindo 0 ou mais de 1.
fonte
</sigh>
A compreensão de sua lista passa por todos os itens do dicionário, encontrando todas as correspondências e, em seguida, retorna apenas a primeira chave. Esta expressão geradora irá iterar apenas o necessário para retornar o primeiro valor:
onde
dd
está o dict. Irá aumentarStopIteration
se nenhuma correspondência for encontrada, então você pode querer capturar isso e retornar uma exceção mais apropriada comoValueError
ouKeyError
.fonte
keys = { key for key,value in dd.items() if value=='value' }
para obter o conjunto de todas as chaves se houver várias correspondências.Existem casos em que um dicionário é um: um mapeamento
Por exemplo,
Sua abordagem está ok se você estiver fazendo apenas uma única pesquisa. No entanto, se você precisar fazer mais de uma pesquisa, será mais eficiente criar um dicionário inverso
Se houver a possibilidade de várias chaves com o mesmo valor, você precisará especificar o comportamento desejado neste caso.
Se seu Python for 2.6 ou mais antigo, você pode usar
fonte
ivd=dict([(v,k) for (k,v) in d.items()])
invd = { v:k for k,v in d.items() }
Esta versão é 26% mais curta que a sua, mas funciona de forma idêntica, mesmo para valores redundantes / ambíguos (retorna a primeira correspondência, como a sua). No entanto, é provavelmente duas vezes mais lento que o seu, porque cria uma lista do dict duas vezes.
Ou se você preferir brevidade em vez de legibilidade, você pode salvar mais um caractere com
E se você preferir eficiência, a abordagem de @PaulMcGuire é melhor. Se houver muitas chaves que compartilham o mesmo valor, é mais eficiente não instanciar essa lista de chaves com uma compreensão de lista e, em vez disso, usar um gerador:
fonte
dict.keys()
edict.values()
têm a garantia de correspondência, desde quedict
não sofra mutação entre as chamadas.Como isso ainda é muito relevante, o primeiro hit do Google e eu acabei de passar algum tempo tentando descobrir isso, postarei minha solução (trabalhando em Python 3):
Ele fornecerá o primeiro valor correspondente.
fonte
Talvez uma aula semelhante a um dicionário, como
DoubleDict
a seguir, seja o que você deseja? Você pode usar qualquer uma das metaclasses fornecidas em conjunto comDoubleDict
ou pode evitar o uso de qualquer metaclasse.fonte
Não, você não pode fazer isso de forma eficiente sem olhar em todas as chaves e verificar todos os seus valores. Portanto, você precisará de
O(n)
tempo para fazer isso. Se você precisar fazer muitas dessas pesquisas, precisará fazer isso de forma eficiente, construindo um dicionário invertido (também pode ser feito emO(n)
) e, em seguida, fazendo uma pesquisa dentro desse dicionário invertido (cada pesquisa levará uma médiaO(1)
).Aqui está um exemplo de como construir um dicionário invertido (que será capaz de fazer um para muitos mapeamentos) a partir de um dicionário normal:
Por exemplo, se o seu
sua
h_reversed
vontade seráfonte
Não há um que eu saiba, mas uma maneira de fazer isso é criar um dict para pesquisa normal por chave e outro dict para pesquisa reversa por valor.
Há um exemplo de tal implementação aqui:
http://code.activestate.com/recipes/415903-two-dict-classes-which-can-lookup-keys-by-value-an/
Isso significa que procurar as chaves por um valor pode resultar em vários resultados que podem ser retornados como uma lista simples.
fonte
Sei que isso pode ser considerado 'desperdício', mas, neste cenário, geralmente armazeno a chave como uma coluna adicional no registro de valor:
é uma troca e parece errado, mas é simples e funciona e, claro, depende de valores serem tuplas em vez de valores simples.
fonte
Faça um dicionário reverso
Se você tiver muitas pesquisas reversas para fazer
fonte
Por meio de valores no dicionário, podem ser objetos de qualquer tipo, eles não podem ser hash ou indexados de outra maneira. Portanto, encontrar a chave pelo valor não é natural para este tipo de coleção. Qualquer consulta como essa pode ser executada apenas em tempo O (n). Portanto, se esta é uma tarefa frequente, você deve procurar alguma indexação de chave como Jon sujjested ou talvez até algum índice espacial (DB ou http://pypi.python.org/pypi/Rtree/ ).
fonte
Estou usando dicionários como uma espécie de "banco de dados", então preciso encontrar uma chave que possa reutilizar. No meu caso, se o valor de uma chave for
None
, posso pegá-la e reutilizá-la sem ter que "alocar" outro id. Só pensei em compartilhar.Gosto deste porque não tenho de tentar detectar erros como
StopIteration
ouIndexError
. Se houver uma chave disponível, entãofree_id
conterá uma. Se não houver, simplesmente seráNone
. Provavelmente não é pythônico, mas eu realmente não queria usar umtry
aqui ...fonte