Accéder aux éléments du dictionnaire Python par index

118

Considérez un dict comme

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

Comment accéder par exemple à un élément particulier de ce dictionnaire? par exemple, je voudrais imprimer le premier élément après un certain formatage du premier élément d'Apple qui dans notre cas est «américain» uniquement?

Informations supplémentaires La structure de données ci-dessus a été créée en analysant un fichier d'entrée dans une fonction python. Une fois créé, il reste cependant le même pour cette exécution.

J'utilise cette structure de données dans ma fonction.

Donc, si le fichier change, la prochaine fois que cette application sera exécutée, le contenu du fichier sera différent et donc le contenu de cette structure de données sera différent mais le format sera le même. Donc, vous voyez que dans ma fonction, je ne sais pas que le premier élément d'Apple est «américain» ou quoi que ce soit d'autre, donc je ne peux pas utiliser directement «américain» comme clé.

Alessandra
la source
2
Pouvez-vous donner un exemple du résultat que vous attendez?
Björn Pollex
3
Que voulez-vous réellement faire avec cette structure? Et connaissez-vous les clés du dict («Apple» et «Grapes» dans votre exemple)? Ou savez-vous seulement que vous obtiendrez un dict de dictés?
juanchopanza
6
N'appelez pas votre dictionnaire dict. Le mot «dict» est déjà un mot-clé en Python. Utilisez autre chose, comme mydict.
Rick soutient Monica le
Remarque: cette question concerne l'accès aux éléments dict par index , ce qui n'a aucun sens car les dictionnaires ne sont pas ordonnés. Pour une question sur l'accès aux éléments dans un dict imbriqué, consultez Python - accès aux valeurs imbriquées dans des dictionnaires .
Aran-Fey
@ Aran-Fey: les choses désordonnées ont un ordre intrinsèque. Unordered! = Pas de commande.
Jamie Marshall

Réponses:

124

Étant donné qu'il s'agit d'un dictionnaire, vous y accédez en utilisant les touches. Pour stocker le dictionnaire sous "Apple", procédez comme suit:

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

Et pour savoir combien d'entre eux sont américains (16), faites comme ceci:

>>> mydict["Apple"]["American"]
'16'
Morten Kristensen
la source
9
Comment faire cela dynamiquement sans connaître la profondeur des éléments?
Ethan Bierlein
3
Que souhaitez-vous savoir exactement? Vous pouvez obtenir les clés d'un dictionnaire avec .keys()afin de pouvoir y accéder dynamiquement.
Morten Kristensen
3
Comme, par exemple, si vous aviez un dictionnaire de profondeur inconnue, par exemple un dictionnaire imbriqué, et que vous avez un élément "n"à une profondeur inconnue, stocké dans un élément inconnu.
Ethan Bierlein
1
C'est une question très large. Compte tenu de votre structure de données, vous écririez alors une fonction ou une classe pour la gérer de manière appropriée. Peut-être pourriez-vous fournir une clé et une stratégie pour essayer de trouver la clé.
Morten Kristensen
1
@EthanBierlein utilise: 'for key, value in dictionary.iteritems ()' pour avoir accès à la fois à la clé et à la valeur
danius
25

Si la question est, si je sais que j'ai un dicton de dictés qui contient `` Apple '' comme fruit et `` américain '' comme type de pomme, j'utiliserais:

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


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

comme d'autres l'ont suggéré. Si à la place la question est, vous ne savez pas si 'Apple' en tant que fruit et 'américain' en tant que type de 'Apple' existent lorsque vous lisez un fichier arbitraire dans votre structure de données dict, vous pouvez faire quelque chose comme:

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

ou mieux encore pour ne pas parcourir inutilement l'ensemble des dictées si vous savez que seul Apple a le type américain:

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

Dans tous ces cas, l'ordre dans lequel les dictionnaires stockent réellement les entrées n'a pas d'importance. Si vous êtes vraiment préoccupé par la commande, vous pouvez envisager d'utiliser un OrderedDict:

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

JoshAdel
la source
20

Comme j'ai remarqué votre description, vous savez juste que votre analyseur vous donnera un dictionnaire que ses valeurs sont aussi un dictionnaire comme ceci:

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

Vous devez donc parcourir votre dictionnaire parent. Si vous souhaitez imprimer ou accéder à toutes les premières clés de dictionnaire de la sampleDict.values()liste, vous pouvez utiliser quelque chose comme ceci:

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

Si vous souhaitez simplement accéder à la première clé du premier élément de sampleDict.values(), cela peut être utile:

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

Si vous utilisez l'exemple que vous avez donné dans la question, je veux dire:

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

La sortie pour le premier code est:

American
Indian

Et la sortie pour le deuxième code est:

American
Zeinab Abbasimazar
la source
10

En prime, j'aimerais offrir une sorte de solution différente à votre problème. Vous semblez avoir affaire à des dictionnaires imbriqués, ce qui est généralement fastidieux, surtout lorsque vous devez vérifier l'existence d'une clé interne.

Il existe quelques bibliothèques intéressantes à ce sujet sur pypi, voici une recherche rapide pour vous.

Dans votre cas spécifique, dict_digger semble approprié.

>>> 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
Flavien Hautbois
la source
8

Vous pouvez utiliser dict['Apple'].keys()[0]pour obtenir la première clé du Appledictionnaire, mais rien ne garantit que ce sera le cas American. L'ordre des clés dans un dictionnaire peut changer en fonction du contenu du dictionnaire et de l'ordre dans lequel les clés ont été ajoutées.

Gabe
la source
sauf si vous utilisez OrderedDictdans la collectionsbibliothèque
Escachator
7

Je sais que cela a 8 ans, mais personne ne semble avoir réellement lu et répondu à la question.

Vous pouvez appeler .values ​​() sur un dict pour obtenir une liste des dictionnaires internes et ainsi y accéder par index.

>>> 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
la source
2
intéressant, j'ai essayé et obtenu 'dict_values' object does not support indexing . Je suppose que cette réponse a besoin d'une mise à jour car vous devez envelopper dict_values ​​pour récupérer une liste
Yuca
1
@Yucca - Vous aviez raison, je n'ai pas testé mon code. La réponse a été mise à jour
Jamie Marshall le
3

Exemple simple pour comprendre comment accéder aux éléments du dictionnaire: -

Créer un dictionnaire

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

Découvrez plus sur les dictionnaires Python et apprenez de manière interactive ici ...

Manish Methani
la source
1

Peu de gens semblent, malgré les nombreuses réponses à cette question, avoir souligné que les dictionnaires sont des mappages non ordonnés, et donc (jusqu'à la bénédiction de l'ordre d'insertion avec Python 3.7) l'idée de la "première" entrée dans un dictionnaire a littéralement fait pas de sens. Et même un OrderedDictne peut être consulté que par index numérique en utilisant des laideurs telles que mydict[mydict.keys()[0]](Python 2 uniquement, car en Python 3 keys()est un itérateur non indexable.)

À partir de 3.7 et en pratique dans 3,6 également - le nouveau comportement a été introduit à l'époque, mais pas inclus dans la spécification du langage jusqu'à 3.7 - itération sur les clés, les valeurs ou les éléments d'un dict (et, je crois, un set également) donnera les objets les moins récemment insérés en premier. Il n'y a toujours pas de moyen simple d'y accéder par index numérique d'insertion.

Quant à la question de la sélection et du «formatage» des éléments, si vous connaissez la clé que vous souhaitez récupérer dans le dictionnaire, vous utiliserez normalement la clé comme indice pour la récupérer ( my_var = mydict['Apple']).

Si vous voulez vraiment pouvoir indexer les éléments par numéro d'entrée (en ignorant le fait que le numéro d'une entrée particulière changera au fur et à mesure des insertions), alors la structure appropriée serait probablement une liste de tuples à deux éléments. Au lieu de

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

vous pourriez utiliser:

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

Sous ce régime, la première entrée est mylist[0]sous forme de liste endex classique, et sa valeur est ('Apple', {'American':'16', 'Mexican':10, 'Chinese':5}). Vous pouvez parcourir toute la liste comme suit:

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

mais si vous savez que vous recherchez la clé "Apple", pourquoi n'utiliseriez-vous pas simplement un dict à la place?

Vous pouvez introduire un niveau supplémentaire d'indirection en mettant en cache la liste des clés, mais la complexité de maintenir deux structures de données en synchronisation ajouterait inévitablement à la complexité de votre code.

holdenweb
la source
0

Avec la petite fonction suivante, creuser dans un dictionnaire en forme d'arbre devient assez facile:

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

Maintenant, dig(mydict, "Apple.Mexican")renvoie 10, tandis que dig(mydict, "Grape")donne le sous-arbre {'Arabian':'25','Indian':'20'}. Si une clé n'est pas contenue dans le dictionnaire, digrenvoieNone .

Notez que vous pouvez facilement changer (ou même paramétrer) le caractère de séparation de '.' à '/', '|' etc.

Heinrich soutient Monica
la source