Acesse um elemento arbitrário em um dicionário em Python

507

Se a mydictnão estiver vazio, eu acedo a um elemento arbitrário como:

mydict[mydict.keys()[0]]

Existe alguma maneira melhor de fazer isso?

Stan
fonte
3
O que ele disse ... essa é apenas uma questão realmente válida se houver apenas um elemento no ditado, ou você não se importa com o que recebe.
royal
5
Sim, eu só preciso acessar qualquer elemento do dict, é por isso que quero acessar o primeiro elemento.
Stan
2
@ Stan: mas, como Greg disse, não há "primeiro" elemento definido no ditado. então talvez você deve mudar a sua pergunta, só para ficar claro
tdihp
10
Eu acho que é uma pergunta válida. Se você precisar acessar um elemento arbitrário e tiver certeza de que o ditado não está vazio, pode ser uma boa ideia pedir o "primeiro", porque o número de itens pode não ser conhecido.
kap
7
@MichaelScheper Você tem que elenco a lista: list(mydict.keys())[0].
Daniel Moskovich 03/08/19

Respostas:

600

No Python 3, de maneira não destrutiva e iterativa:

next(iter(mydict.values()))

No Python 2, de maneira não destrutiva e iterativa:

mydict.itervalues().next()

Se você deseja que ele funcione no Python 2 e 3, você pode usar o sixpacote:

six.next(six.itervalues(mydict))

embora neste momento seja bastante enigmático e prefiro seu código.

Se você deseja remover qualquer item, faça:

key, value = mydict.popitem()

Observe que "primeiro" pode não ser um termo apropriado aqui, porque dictnão é um tipo ordenado em Python <3.6. Python 3.6+ dictssão encomendados.

doublep
fonte
35
Você não quer dizer dict.iterkeys().next()?
precisa
12
@ John Machin: Bem, a pergunta parece acessar o valor associado à primeira chave, então é isso que faço na resposta também.
doublep
5
Isso parece melhor: dict.values().__iter__().__next__():)
Vitaly Zdanevich
17
É irritante que dict.keys () não seja diretamente iterável.
Semiomant
3
para um popitem não destrutivo, você pode fazer uma cópia (rasa):key, value = dict(d).popitem()
Pelle
140

Se você precisar acessar apenas um elemento (sendo o primeiro por acaso, já que os dict não garantem a ordem), basta fazer isso no Python 2 :

my_dict.keys()[0]     -> key of "first" element
my_dict.values()[0]   -> value of "first" element
my_dict.items()[0]    -> (key, value) tuple of "first" element

Observe que (no melhor de meu conhecimento) o Python não garante que duas chamadas sucessivas para qualquer um desses métodos retornem a lista com a mesma ordem. Isso não é suportado no Python3.

no Python 3 :

list(my_dict.keys())[0]     -> key of "first" element
list(my_dict.values())[0]   -> value of "first" element
list(my_dict.items())[0]    -> (key, value) tuple of "first" element
swK
fonte
90
Isso só funciona em Python 2.x, para 3.x você tem que usarlist(my_dict.keys())[0]
alldayremix
6
Então, que classe de complexidade é essa? Certamente, list(my_dict.keys())[0]não é preguiçoso?
Evgeni Sergeev
1
Para esclarecer, o que @alldayremix quis dizer com esse comentário nos resultados do python 3.x my_dict.function () não oferece suporte à indexação, é por isso que primeiro devemos convertê-lo em uma lista e depois usar o índice [0]
Noki
57

Em python3, o caminho:

dict.keys() 

retorne um valor no tipo: dict_keys (), obteremos um erro ao obter o 1º membro das chaves do dict dessa maneira:

dict.keys()[0]
TypeError: 'dict_keys' object does not support indexing

Finalmente, eu converti dict.keys () para list @ 1st e obtive o 1º membro pelo método de emenda de lista:

list(dict.keys())[0]
Xb74Dkjb
fonte
Esta é a solução mais fácil e funciona em python2 e python3.
mattmilten
Pelo meu dinheiro. Digo isto resposta é o mais intuitivo
Thomas Valadez
Sim, mas isso não responde à pergunta do OP, que é como chegar aos VALUES, não às chaves.
Mike Williamson
1
@ MikeWilliamson, esperamos que a maioria dos leitores saiba como obter o valor correspondente, dado uma chave, de um ditado python.
eric
5
Para obter um item arbitrário, não uma chave arbitrária, você pode fazer analogamente list(dict.values())[0].
Jhin
24

pegar uma chave

next(iter(mydict))

para obter um valor

next(iter(mydict.values()))

para obter os dois

next(iter(mydict.items())) # or next(iter(mydict.viewitems())) in python 2

Os dois primeiros são Python 2 e 3. Os dois últimos são preguiçosos no Python 3, mas não no Python 2.

maxbellec
fonte
16

Como outros mencionados, não há "primeiro item", pois os dicionários não têm ordem garantida (eles são implementados como tabelas de hash). Se você quiser, por exemplo, o valor correspondente à menor chave, thedict[min(thedict)]fará isso. Se você se importa com a ordem em que as chaves foram inseridas, ou seja, por "primeiro" você quer dizer "inserido mais cedo", no Python 3.1 você pode usar coleções.OrderedDict , que também está no Python 2.7; para versões mais antigas do Python, baixe, instale e use o dict backport ordenado (2.4 e posterior) que você pode encontrar aqui .

Python 3.7 Agora os ditados são ordenados por inserção.

Alex Martelli
fonte
11

Que tal agora. Ainda não mencionado aqui.

py 2 e 3

a = {"a":2,"b":3}
a[list(a)[0]] # the first element is here
>>> 2
animaacija
fonte
5
dict.values()retorna uma visualização, então deve ser O (1). list(a)retorna uma nova lista, assim seria O (n).
boycy
Também parece que ele não funciona em python2 se a = { "A": { "1"}}
qasimzee
11

Ignorando os problemas relacionados à ordenação de ditados, isso pode ser melhor:

next(dict.itervalues())

Dessa forma, evitamos a pesquisa de itens e geramos uma lista de chaves que não usamos.

Python3

next(iter(dict.values()))
Matt Joiner
fonte
2
values ​​() fará uma cópia de todos os valores (assim como as teclas () das chaves), portanto, isso fará muitas operações O (n ^ 2).
Glenn Maynard
Então, a versão dos OPs? Vou mudar isso para usar um iterador então.
Matt Joiner
4
Este é apenas o Python 2. Para o Python 3, precisamos next(iter(dict.values()))obter o mesmo resultado sem criar a lista.
kap
6

Em python3

list(dict.values())[0]
Oleg Matei
fonte
4
O que acontece se o dicionário tiver um bilhão de entradas? :)
Fábio Dias
2

Você sempre pode fazer:

for k in sorted(d.keys()):
    print d[k]

Isto lhe dará um consistentemente classificada (com respeito ao builtin set .hash () eu acho) de teclas que pode processar em se a ordenação tem algum significado para você. Isso significa que, por exemplo, os tipos numéricos são classificados de forma consistente, mesmo se você expandir o dicionário.

EXEMPLO

# lets create a simple dictionary
d = {1:1, 2:2, 3:3, 4:4, 10:10, 100:100}
print d.keys()
print sorted(d.keys())

# add some other stuff
d['peter'] = 'peter'
d['parker'] = 'parker'
print d.keys()
print sorted(d.keys())

# some more stuff, numeric of different type, this will "mess up" the keys set order
d[0.001] = 0.001
d[3.14] = 'pie'
d[2.71] = 'apple pie'
print d.keys()
print sorted(d.keys())

Observe que o dicionário é classificado quando impresso. Mas o conjunto de chaves é essencialmente um hashmap!

Philipp Meier
fonte
2

Para o Python 2 e 3:

import six

six.next(six.itervalues(d))
oblalex
fonte
Isso não fornece uma resposta para a pergunta. Para criticar ou solicitar esclarecimentos a um autor, deixe um comentário abaixo da postagem.
Martin Tournoij
Isso responde exatamente à pergunta de Is there any better way to do this?maneira curta.
oblalex
Esta resposta já foi dada duas vezes, uma das quais existe neste site há quase 5 anos. Este é um comentário sobre outra resposta (como em: veja como melhorar a resposta para fazê-la funcionar com o Python 2 e 3 ), e não uma resposta "nova", como tal. Sistema de revisão do SO colocado automaticamente uma nota um pouco inútil neste caso ...
Martin Tournoij
Não senhor. Você adicionou essa variante à sua resposta de 5 anos apenas 17 horas atrás, 1 hora depois que eu escrevi essa resposta. Tente usar 'encontrar' nesta página para a palavra 'seis' e você encontrará apenas 6 correspondências apenas nessas 2 respostas. Enfim, essa resposta realmente te incomoda? Eu acho que isso pode ajudar outras pessoas no futuro e está tudo bem. Então, qual é o problema?
oblalex
Isso porque IMHO esta resposta deveria ter sido uma edição para esse post em primeiro lugar. Sem a edição, as pessoas teriam que rolar várias páginas para baixo para ver sua resposta; você acha que é mais útil do que editar uma resposta altamente votada que é quase exatamente igual à sua?
Martin Tournoij
0
first_key, *rest_keys = mydict
user1994083
fonte
11
Obrigado por este trecho de código, que pode fornecer ajuda imediata e limitada. Uma explicação adequada melhoraria bastante seu valor a longo prazo , mostrando por que essa é uma boa solução para o problema e a tornaria mais útil para futuros leitores com outras perguntas semelhantes. Por favor edite sua resposta para adicionar alguma explicação, incluindo as suposições que você fez.
Suraj Rao
-1

Nenhuma biblioteca externa funciona em Python 2.7 e 3.x:

>>> list(set({"a":1, "b": 2}.values()))[0]
1

Para chave arbitrária, deixe de fora .values ​​()

>>> list(set({"a":1, "b": 2}))[0]
'a'
Thomas Browne
fonte
-2

A subclassificação dicté um método, embora não seja eficiente. Aqui, se você fornecer um número inteiro, ele retornará d[list(d)[n]]; caso contrário, acesse o dicionário conforme o esperado:

class mydict(dict):
    def __getitem__(self, value):
        if isinstance(value, int):
            return self.get(list(self)[value])
        else:
            return self.get(value)

d = mydict({'a': 'hello', 'b': 'this', 'c': 'is', 'd': 'a',
            'e': 'test', 'f': 'dictionary', 'g': 'testing'})

d[0]    # 'hello'
d[1]    # 'this'
d['c']  # 'is'
jpp
fonte