Eu tenho um dictionary
: chaves são seqüências de caracteres, os valores são inteiros.
Exemplo:
stats = {'a':1000, 'b':3000, 'c': 100}
Gostaria de receber 'b'
como resposta, já que é a chave com um valor mais alto.
Fiz o seguinte, usando uma lista intermediária com tuplas de valor-chave invertidas:
inverse = [(value, key) for key, value in stats.items()]
print max(inverse)[1]
Essa é a melhor (ou até mais elegante) abordagem?
python
dictionary
max
ricafeal
fonte
fonte
max(stats)
?max(stats)
usará os rótulos como chaves (retornará'c'
, dado que é o rótulo máximo),max(stats, key=lambda key: stats[key])
é o que foi o OP (que retornará'b'
, rótulo com o valor máximo indexado). Está mais claro?Respostas:
Você pode usar
operator.itemgetter
para isso:E em vez de criar uma nova lista no uso de memória
stats.iteritems()
. Okey
parâmetro para amax()
função é uma função que calcula uma chave usada para determinar como classificar itens.Observe que, se você tiver outro par de valores-chave 'd': 3000, esse método retornará apenas um dos dois , embora ambos tenham o valor máximo.
Se você estiver usando Python3:
fonte
max(stats.iterkeys(), key=(lambda key: stats[key]))
key=lambda x: x[1]
?max(stats, key=lambda key: stats[key])
fonte
stats[max(stats, key=stats.get)]
max_value = max(stats.values()); {key for key, value in stats.items() if value == max_value}
Testei MUITAS variantes, e esta é a maneira mais rápida de retornar a chave do dict com o valor máximo:
Para lhe dar uma ideia, aqui estão alguns métodos candidatos:
O dicionário de teste:
E os resultados do teste no Python 3.2:
E no Python 2.7:
Você pode ver que
f1
é o mais rápido no Python 3.2 e 2.7 (ou, mais completamente,keywithmaxval
na parte superior deste post)fonte
f7
é comof1
, apenas não dar um nome a um objeto intermediário.f7
deve ser (muito ligeiramente) mais rápido quef1
, não muito mais lento. E é isso que eu recebo:>>> timeit.timeit("f1()","from __main__ import f1, f7, d1", number=10000) 0.26785888786807277 >>> timeit.timeit("f7()","from __main__ import f1, f7, d1", number=10000) 0.26770628307832567
Se você precisar conhecer apenas uma chave com o valor máximo, poderá fazê-lo sem
iterkeys
ouiteritems
porque a iteração através do dicionário no Python é iteração através das suas chaves.EDITAR:
Dos comentários, @ user1274878:
Sim...
max
O
key
argumento opcional descreve como comparar elementos para obter o máximo entre eles:Os valores retornados serão comparados.
Dict
Python dict é uma tabela de hash. Uma chave do dict é um hash de um objeto declarado como uma chave. Devido a razões de desempenho, a iteração foi implementada como um ditado como iteração através de suas chaves.
Portanto, podemos usá-lo para livrar a operação de obter uma lista de chaves.
Fecho
A
stats
variável disponível através do__closure__
atributo dalambda
função como um ponteiro para o valor da variável definida no escopo pai.fonte
Exemplo:
se você quiser encontrar o valor máximo com sua chave, talvez seguir possa ser simples, sem nenhuma função relevante.
a saída é a chave que tem o valor máximo.
fonte
Aqui está outro:
A função
key
simplesmente retorna o valor que deve ser usado para classificação emax()
retorna o elemento exigido imediatamente.fonte
max(stats, key=lambda k: stats[k])
Se você não se importa com valor (eu ficaria surpreso, mas), você pode fazer:
Eu gosto mais da descompactação da tupla do que um subscrito [0] no final da expressão. Eu nunca gosto muito da legibilidade das expressões lambda, mas acho essa melhor do que o operator.itemgetter (1) IMHO.
fonte
_
poderia ser usado em vez deignored
.ignored
parece muito feio, mas algumas pessoas são contra o uso_
por várias razões. Acho que o primeiro trecho é bom mesmo se você ignorar o valorDado que mais de uma entrada, tenho o valor máximo. Eu faria uma lista das chaves que têm o valor máximo como seu valor.
Isso fornecerá 'b' e qualquer outra chave máxima também.
Nota: Para python 3, use em
stats.items()
vez destats.iteritems()
fonte
max
fosse cara (por exemplo, um dicionário LONGO), eu recomendaria[key for m in [max(stats.values())] for key,val in stats.iteritems() if val == m]
se você quer uma única linha, caso contrário, calcule comm = ...
antecedência.Você pode usar:
Para retornar a chave, par de valores use:
fonte
Para obter a chave / valor máximo do dicionário
stats
:>>> max(stats.items(), key = lambda x: x[0]) ('c', 100)
>>> max(stats.items(), key = lambda x: x[1]) ('b', 3000)
Obviamente, se você deseja obter apenas a chave ou o valor do resultado, pode usar a indexação de tupla. Por exemplo, para obter a chave correspondente ao valor máximo:
>>> max(stats.items(), key = lambda x: x[1])[0] 'b'
Explicação
O método de dicionário
items()
no Python 3 retorna um objeto de exibição do dicionário. Quando esse objeto de exibição é iterado, pelamax
função, ele gera os itens do dicionário como tuplas do formulário(key, value)
.>>> list(stats.items()) [('c', 100), ('b', 3000), ('a', 1000)]
Quando você usa a
lambda
expressãolambda x: x[1]
, em cada iteração,x
é uma dessas tuplas(key, value)
. Portanto, escolhendo o índice certo, você seleciona se deseja comparar por chaves ou por valores.Python 2
Para versões do Python 2.2+, o mesmo código funcionará. No entanto, é melhor usar o
iteritems()
método de dicionário em vez doitems()
desempenho.Notas
Esta resposta é baseada nos comentários da resposta de Climbs_lika_Spyder .
O código usado foi testado no Python 3.5.2 e Python 2.7.10.
fonte
fonte
Pelas soluções iteradas por meio de comentários na resposta selecionada ...
No Python 3:
No Python 2:
fonte
Cheguei aqui procurando como retornar com
mydict.keys()
base no valor demydict.values()
. Em vez de apenas a chave retornada, eu estava procurando retornar o número x superior de valores.Esta solução é mais simples do que usar a
max()
função e você pode alterar facilmente o número de valores retornados:Se você deseja a única chave de classificação mais alta, basta usar o índice:
Se você deseja as duas principais chaves de classificação mais alta, use o fatiamento de lista:
fonte
max()
. É claro que é o mais rápido. Pensei em oferecer uma solução diferente com o benefício de corte, o que era mais útil para mim no momentoNão fiquei satisfeito com nenhuma dessas respostas.
max
sempre escolhe a primeira chave com o valor máximo. O dicionário pode ter várias chaves com esse valor.Postar esta resposta para o caso de ajudar alguém. Veja a publicação SO abaixo
Qual o máximo que o Python escolhe em caso de empate?
fonte
Com
collections.Counter
você poderia fazerSe apropriado, você pode simplesmente começar com um vazio
collections.Counter
e adicionar a elefonte
Uma fila de heap é uma solução generalizada que permite extrair as n chaves principais ordenadas por valor:
Nota
dict.__getitem__
é o método chamado pelo açúcar sintáticodict[]
. Ao contráriodict.get
, ele retornaráKeyError
se uma chave não for encontrada, o que aqui não pode ocorrer.fonte
max((value, key) for key, value in stats.items())[1]
fonte
+1 à solução mais simples de @Aric Coady .
E também uma maneira de selecionar aleatoriamente uma das chaves com valor máximo no dicionário:
fonte
fonte
E se:
fonte
zip(stats.keys(), stats.values())
é apenas uma maneira mais longa de escreverstats.items()
. Depois de fazer essa alteração, sua resposta será quase idêntica a várias respostas mais antigas.items
não é o mesmo quezip
. Apenas produz o mesmo resultado.Testei a resposta aceita E a solução mais rápida do @wolf contra um loop muito básico e o loop foi mais rápido que ambos:
resultados:
fonte
Para usuários científicos de python, aqui está uma solução simples usando o Pandas:
fonte
No caso de você ter mais de uma chave com o mesmo valor, por exemplo:
Você pode obter uma coleção com todas as chaves com valor máximo da seguinte maneira:
fonte
Muito mais simples de entender a abordagem:
Saída: ['a', 'g']
Agora você pode escolher apenas uma chave:
fonte