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?


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.


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

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]

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.


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.


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

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()))

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


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!


2

Para o Python 2 e 3:

import six

six.next(six.itervalues(d))

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


-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'

-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'
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.