Accediendo a elementos del diccionario de Python por índice

118

Considere un dictado como

mydict = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} }

¿Cómo accedo, por ejemplo, a un elemento particular de este diccionario? por ejemplo, me gustaría imprimir el primer elemento después de formatear el primer elemento de Apple, que en nuestro caso es solo "americano".

Información adicional La estructura de datos anterior se creó analizando un archivo de entrada en una función de Python. Sin embargo, una vez creado, sigue siendo el mismo para esa ejecución.

Estoy usando esta estructura de datos en mi función.

Entonces, si el archivo cambia, la próxima vez que se ejecute esta aplicación, el contenido del archivo será diferente y, por lo tanto, el contenido de esta estructura de datos será diferente pero el formato será el mismo. Así que, en mi función, no sé si el primer elemento en Apple es 'americano' o cualquier otra cosa, así que no puedo usar directamente 'americano' como clave.

Alessandra
fuente
2
¿Puede dar un ejemplo del resultado que espera?
Björn Pollex
3
¿Qué quieres hacer realmente con esta estructura? ¿Y conoces las claves del dict ('Apple' y 'Grapes' en tu ejemplo)? ¿O solo sabe que obtendrá un dictado de dictados?
juanchopanza
6
No llames a tu diccionario dict. La palabra 'dict' ya es una palabra clave en Python. Usa algo más, como mydict.
Rick apoya a Monica
Nota: esta pregunta trata sobre el acceso a los elementos de dictado por índice , lo que no tiene sentido porque los dictados están desordenados. Para obtener una pregunta sobre cómo acceder a elementos en un diccionario anidado, consulte Python: acceder a valores anidados dentro de los diccionarios .
Aran-Fey
@ Aran-Fey: las cosas desordenadas tienen un orden intrínseco. ¡Desordenado! = Sin pedido.
Jamie Marshall

Respuestas:

122

Dado que se trata de un diccionario se accede a él mediante las teclas. Para obtener el diccionario almacenado en "Apple", haga lo siguiente:

>>> mydict["Apple"]
{'American': '16', 'Mexican': 10, 'Chinese': 5}

Y para saber cuántos de ellos son estadounidenses (16), haga lo siguiente:

>>> mydict["Apple"]["American"]
'16'
Morten Kristensen
fuente
9
¿Cómo se puede hacer esto de forma dinámica sin conocer la profundidad de los elementos?
Ethan Bierlein
3
¿Qué le gustaría saber exactamente? Puede obtener las claves de un diccionario con .keys()para poder acceder a ellas de forma dinámica.
Morten Kristensen
3
Como, por ejemplo, si tuviera un diccionario de profundidad desconocida, por ejemplo, un diccionario anidado, y tiene un elemento "n"a una profundidad desconocida, almacenado en un elemento desconocido.
Ethan Bierlein
1
Esa es una pregunta muy amplia. Dada su estructura de datos, entonces escribiría una función o clase para manejarla adecuadamente. Quizás podría proporcionar una clave y una estrategia para tratar de encontrar la clave.
Morten Kristensen
1
@EthanBierlein usa: 'para clave, valor en dictionary.iteritems ()' para tener acceso tanto a la clave como al valor
danius
25

Si la pregunta es, si sé que tengo un dictado de dictados que contiene 'Apple' como fruta y 'Americano' como un tipo de manzana, usaría:

myDict = {'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
          'Grapes':{'Arabian':'25','Indian':'20'} }


print myDict['Apple']['American']

como sugirieron otros. Si, en cambio, la pregunta es, no sabe si 'Apple' como fruta y 'American' como un tipo de 'Apple' existen cuando lee un archivo arbitrario en su estructura de datos dict of dict, podría hacer algo como:

print [ftype['American'] for f,ftype in myDict.iteritems() if f == 'Apple' and 'American' in ftype]

o mejor aún, para que no repita innecesariamente todo el dictado de dictados si sabe que solo Apple tiene el tipo estadounidense:

if 'Apple' in myDict:
    if 'American' in myDict['Apple']:
        print myDict['Apple']['American']

En todos estos casos, no importa en qué orden los diccionarios almacenan realmente las entradas. Si está realmente preocupado por el pedido, podría considerar usar un OrderedDict:

http://docs.python.org/dev/library/collections.html#collections.OrderedDict

JoshAdel
fuente
20

Como noté su descripción, solo sabe que su analizador le dará un diccionario cuyos valores también son diccionario como este:

sampleDict = {
              "key1": {"key10": "value10", "key11": "value11"},
              "key2": {"key20": "value20", "key21": "value21"}
              }

Entonces tienes que iterar sobre tu diccionario principal. Si desea imprimir o acceder a todas las primeras claves del diccionario en la sampleDict.values()lista, puede usar algo como esto:

for key, value in sampleDict.items():
    print value.keys()[0]

Si solo desea acceder a la primera clave del primer elemento sampleDict.values(), esto puede ser útil:

print sampleDict.values()[0].keys()[0]

Si usa el ejemplo que dio en la pregunta, quiero decir:

sampleDict = {
              'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
              'Grapes':{'Arabian':'25','Indian':'20'}
              }

La salida del primer código es:

American
Indian

Y la salida para el segundo código es:

American
Zeinab Abbasimazar
fuente
10

Como beneficio adicional, me gustaría ofrecer una solución diferente a su problema. Parece estar tratando con diccionarios anidados, lo que suele ser tedioso, especialmente cuando tiene que comprobar la existencia de una clave interna.

Hay algunas bibliotecas interesantes con respecto a esto en pypi, aquí hay una búsqueda rápida para usted.

En su caso específico, dict_digger parece adecuado.

>>> import dict_digger
>>> d = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} 
}

>>> print(dict_digger.dig(d, 'Apple','American'))
16
>>> print(dict_digger.dig(d, 'Grapes','American'))
None
Flavio Hautbois
fuente
8

Puede usar dict['Apple'].keys()[0]para obtener la primera clave en el Applediccionario, pero no hay garantía de que lo sea American. El orden de las claves en un diccionario puede cambiar según el contenido del diccionario y el orden en que se agregaron las claves.

Gabe
fuente
a menos que lo use OrderedDicten la collectionsbiblioteca
Escachator
7

Sé que esto tiene 8 años, pero nadie parece haber leído y respondido la pregunta.

Puede llamar .values ​​() en un dictado para obtener una lista de los dictados internos y así acceder a ellos por índice.

>>> mydict = {
...  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
...  'Grapes':{'Arabian':'25','Indian':'20'} }

>>>mylist = list(mydict.values())
>>>mylist[0]
{'American':'16', 'Mexican':10, 'Chinese':5},
>>>mylist[1]
{'Arabian':'25','Indian':'20'}

>>>myInnerList1 = list(mylist[0].values())
>>>myInnerList1
['16', 10, 5]
>>>myInnerList2 = list(mylist[1].values())
>>>myInnerList2
['25', '20']
Jamie Marshall
fuente
2
interesante, probé esto y obtuve 'dict_values' object does not support indexing . Supongo que esta respuesta necesita una actualización, ya que necesita ajustar dict_values ​​para recuperar una lista
Yuca
1
@Yucca - Tenías razón, no probé mi código. La respuesta ha sido actualizada
Jamie Marshall
2

Ejemplo simple para entender cómo acceder a elementos en el diccionario: -

Crear un diccionario

d = {'dog' : 'bark', 'cat' : 'meow' } 
print(d.get('cat'))
print(d.get('lion'))
print(d.get('lion', 'Not in the dictionary'))
print(d.get('lion', 'NA'))
print(d.get('dog', 'NA'))

Explore más sobre los diccionarios de Python y aprenda interactivamente aquí ...

Manish Methani
fuente
0

Pocas personas parecen, a pesar de las muchas respuestas a esta pregunta, haber señalado que los diccionarios son mapeos desordenados, por lo que (hasta la bendición del orden de inserción con Python 3.7) la idea de la "primera" entrada en un diccionario literalmente se hizo sin sentido. E incluso OrderedDictsolo se puede acceder a un índice numérico utilizando uglinesses como mydict[mydict.keys()[0]](solo Python 2, ya que en Python 3 keys()es un iterador no subscriptable).

Desde 3.7 en adelante y en la práctica también en 3.6 - el nuevo comportamiento se introdujo entonces, pero no se incluyó como parte de la especificación del lenguaje hasta 3.7 - iteración sobre las claves, valores o elementos de un dict (y, creo, un set also) producirá primero los objetos insertados menos recientemente. Todavía no existe una forma sencilla de acceder a ellos mediante el índice numérico de inserción.

En cuanto a la cuestión de seleccionar y "formatear" elementos, si conoce la clave que desea recuperar en el diccionario, normalmente usaría la clave como subíndice para recuperarla (my_var = mydict['Apple'] ).

Si realmente desea poder indexar los elementos por número de entrada (ignorando el hecho de que el número de una entrada en particular cambiará a medida que se realizan las inserciones), entonces la estructura apropiada probablemente sería una lista de tuplas de dos elementos. En vez de

mydict = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} }

puedes usar:

mylist = [
    ('Apple', {'American':'16', 'Mexican':10, 'Chinese':5}),
    ('Grapes', {'Arabian': '25', 'Indian': '20'}
]

Bajo este régimen, la primera entrada está mylist[0]en la forma clásica indexada por lista, y su valor es ('Apple', {'American':'16', 'Mexican':10, 'Chinese':5}). Puede iterar sobre toda la lista de la siguiente manera:

for (key, value) in mylist:  # unpacks to avoid tuple indexing
    if key == 'Apple':
        if 'American' in value:
            print(value['American'])

pero si sabes que estás buscando la clave "Apple", ¿por qué no usarías un dict en su lugar?

Podría introducir un nivel adicional de direccionamiento indirecto almacenando en caché la lista de claves, pero la complejidad de mantener dos estructuras de datos sincronizadas inevitablemente se sumaría a la complejidad de su código.

holdenweb
fuente
0

Con la siguiente función pequeña, buscar en un diccionario en forma de árbol se vuelve bastante fácil:

def dig(tree, path):
    for key in path.split("."):
        if isinstance(tree, dict) and tree.get(key):
            tree = tree[key]
        else:
            return None
    return tree

Ahora, dig(mydict, "Apple.Mexican")devuelve 10, mientras que dig(mydict, "Grape")produce el subárbol {'Arabian':'25','Indian':'20'}. Si una clave no está contenida en el diccionario, digdevuelveNone .

Tenga en cuenta que puede cambiar fácilmente (o incluso parametrizar) el carácter separador de '.' a '/', '|' etc.

Heinrich apoya a Monica
fuente