Acceda a un elemento arbitrario en un diccionario en Python


507

Si a mydictno está vacío, accedo a un elemento arbitrario como:

mydict[mydict.keys()[0]]

¿Hay alguna forma mejor de hacer esto?


3
Lo que dijo ... esta es realmente una pregunta válida si solo hay un elemento en el dict, o si no te importa cuál regresas.
real

55
Sí, solo necesito acceder a cualquier elemento en el dict, así que es por eso que quiero acceder al primer elemento.
Stan

2
@Stan: pero como dijo Greg, no hay un "primer" elemento definido en el dict. así que tal vez deberías cambiar tu pregunta, solo para que quede claro
tdihp

10
Creo que es una pregunta válida. Si necesita acceder a un elemento arbitrario, y está seguro de que el dict no está vacío, puede ser una buena idea pedir el "primero", porque es posible que no se conozca el número de elementos.
kap

77
@MichaelScheper tienen que desechar a la lista: list(mydict.keys())[0].
Daniel Moskovich

Respuestas:


600

En Python 3, de forma no destructiva e iterativa:

next(iter(mydict.values()))

En Python 2, de forma no destructiva e iterativa:

mydict.itervalues().next()

Si desea que funcione tanto en Python 2 como en 3, puede usar el sixpaquete:

six.next(six.itervalues(mydict))

aunque en este punto es bastante críptico y prefiero tu código.

Si desea eliminar algún elemento, haga lo siguiente:

key, value = mydict.popitem()

Tenga en cuenta que "primero" puede no ser un término apropiado aquí porque dictno es un tipo ordenado en Python <3.6. Python 3.6+ dictsestán ordenados.


35
No quiere decir dict.iterkeys().next()?
John Machin

12
@ John Machin: Bueno, la pregunta parece tener acceso al valor asociado con la primera clave, así que eso es lo que hago también en la respuesta.
doublep

55
esto se ve mejor: dict.values().__iter__().__next__():)
Vitaly Zdanevich

17
Es molesto que dict.keys () no sea directamente iterable.
semiomante

3
para un popitem no destructivo se puede hacer una (superficial) copiar:key, value = dict(d).popitem()
Pelle

140

Si solo necesita acceder a un elemento (siendo el primero por casualidad, ya que los dictados no garantizan el pedido), simplemente puede hacer esto en 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

Tenga en cuenta que (a mi leal saber y entender) Python no garantiza que 2 llamadas sucesivas a cualquiera de estos métodos devuelvan la lista con el mismo orden. Esto no es compatible con Python3.

en 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
Eso solo funciona en Python 2.x, para 3.x tienes que usarlist(my_dict.keys())[0]
alldayremix

66
Entonces, ¿qué clase de complejidad es esta? Seguramente, list(my_dict.keys())[0]no es vago?
Evgeni Sergeev

1
Para aclarar, lo que @alldayremix quiso decir con ese comentario está en python 3.x my_dict.function () los resultados no son compatibles con la indexación, es por eso que primero debemos convertirlo en una lista y luego podemos usar el índice [0]
Noki

57

En python3, El camino:

dict.keys() 

devuelve un valor en tipo: dict_keys (), obtendremos un error cuando obtengamos el primer miembro de las claves de dict de esta manera:

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

Finalmente, convierto dict.keys () a list @ 1st, y obtuve el primer miembro por el método de empalme de lista:

list(dict.keys())[0]

Esta es la solución más fácil y funciona tanto en python2 como en python3.
mattmilten

Por mi dinero. Yo digo que esta respuesta es la más intuitiva
Thomas Valadez

Sí, pero esto no responde a la pregunta OP, que es cómo llegar a los VALORES, no a las claves.
Mike Williamson

1
@MikeWilliamson, con suerte, la mayoría de los lectores sabrán cómo obtener el valor correspondiente, dada una clave, de un dict de Python.
Eric

55
Para obtener un elemento arbitrario, no una clave arbitraria, puede hacerlo de forma análoga list(dict.values())[0].
jhin

24

obtener una llave

next(iter(mydict))

para obtener un valor

next(iter(mydict.values()))

para obtener ambos

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

Los dos primeros son Python 2 y 3. Los dos últimos son vagos en Python 3, pero no en Python 2.


16

Como otros mencionaron, no hay un "primer elemento", ya que los diccionarios no tienen un orden garantizado (se implementan como tablas hash). Si desea, por ejemplo, el valor correspondiente a la clave más pequeña, thedict[min(thedict)]lo hará. Si le importa el orden en que se insertaron las claves, es decir, por "primero" quiere decir "insertado más temprano", entonces en Python 3.1 puede usar collections.OrderedDict , que también se encuentra en Python 2.7; para versiones anteriores de Python, descargue, instale y use el backport dict ordenado (2.4 y posterior) que puede encontrar aquí .

Python 3.7 Ahora los dictados están ordenados por inserción.


11

Qué tal esto. No se menciona aquí todavía.

py 2 y 3

a = {"a":2,"b":3}
a[list(a)[0]] # the first element is here
>>> 2

55
dict.values()devuelve una vista, por lo que debería ser O (1). list(a)devuelve una nueva lista, por lo que sería O (n).
boycy

También parece que no funciona en python2 si a = {"a": {"1"}}
qasimzee

11

Ignorando los problemas relacionados con el pedido de dict, esto podría ser mejor:

next(dict.itervalues())

De esta forma, evitamos la búsqueda de elementos y generamos una lista de claves que no usamos.

Python3

next(iter(dict.values()))

2
valores () hará una copia de todos los valores (al igual que las teclas () para las teclas), por lo que esto hará muchas operaciones O (n ^ 2).
Glenn Maynard

Entonces, ¿será la versión de OP? Cambiaré esto para usar un iterador entonces.
Matt Joiner el

44
Esto es solo Python 2. Para Python 3, necesitamos next(iter(dict.values()))obtener el mismo resultado sin crear la lista.
kap


2

Siempre puedes hacer:

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

Esto le dará una forma consistente ordenados (con respecto al orden interna conjunto .hash () supongo) de teclas que puede procesar en la clasificación si tiene algún significado para ti. Eso significa, por ejemplo, que los tipos numéricos se ordenan de manera consistente incluso si expande el diccionario.

EJEMPLO

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

Tenga en cuenta que el diccionario se ordena cuando se imprime. ¡Pero el conjunto de claves es esencialmente un hashmap!


2

Para Python 2 y 3:

import six

six.next(six.itervalues(d))

Esto no proporciona una respuesta a la pregunta. Para criticar o solicitar una aclaración de un autor, deje un comentario debajo de su publicación.
Martin Tournoij

Esto responde exactamente la pregunta Is there any better way to do this?de manera breve.
oblalex

Esta respuesta ya se ha dado dos veces, una de las cuales ha estado en este sitio durante casi 5 años. Este es un comentario sobre otra respuesta (como en: aquí se explica cómo mejorar la respuesta para que funcione con Python 2 y 3 ), y no una respuesta "nueva", como tal. El sistema de revisión de SO colocó automáticamente una nota algo inútil en este caso ...
Martin Tournoij

No señor. Agregó esta variante a su respuesta de 5 años hace solo 17 horas, 1 hora después de que escribí esta respuesta. Intente usar 'buscar' en esta página para 'seis' palabras y encontrará solo 6 coincidencias solo en estas 2 respuestas. De todos modos, ¿esta respuesta realmente te molesta? Creo que esto podría ayudar a otras personas en el futuro y está bien. Entonces, ¿cuál es el trato?
oblalex

Eso es porque, en mi humilde opinión, esta respuesta debería haber sido una edición de esa publicación en primer lugar. Sin la edición, las personas tendrían que desplazarse varias páginas hacia abajo para ver su respuesta; ¿Crees que es más útil que editar una respuesta altamente votada que es casi exactamente la misma que la tuya?
Martin Tournoij


-1

Sin bibliotecas externas, funciona tanto en Python 2.7 como en 3.x:

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

Para la clave aribtrary simplemente omita .values ​​()

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

-2

La subclasificación dictes un método, aunque no eficiente. Aquí, si proporciona un número entero, volverá d[list(d)[n]]; de lo contrario, acceda al diccionario como se esperaba:

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'
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.