Accesso agli elementi del dizionario Python per indice


118

Considera un dict come

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

Come si accede, ad esempio, a un particolare elemento di questo dizionario? per esempio, vorrei stampare il primo elemento dopo aver formattato il primo elemento di Apple che nel nostro caso è solo "americano"?

Informazioni aggiuntive La struttura dati sopra è stata creata analizzando un file di input in una funzione python. Una volta creato, tuttavia, rimane lo stesso per quella corsa.

Sto usando questa struttura dati nella mia funzione.

Quindi, se il file cambia, la prossima volta che questa applicazione viene eseguita il contenuto del file sarà diverso e quindi il contenuto di questa struttura dati sarà diverso ma il formato sarà lo stesso. Quindi vedete io nella mia funzione non so che il primo elemento in Apple sia "americano" o qualsiasi altra cosa, quindi non posso usare direttamente "americano" come chiave.


2
Puoi fornire un esempio dell'output che ti aspetti?
Björn Pollex

3
Cosa vuoi veramente fare con questa struttura? E conosci le chiavi del dict ("Apple" e "Grapes" nel tuo esempio)? O sai solo che riceverai un dict of dict?
juanchopanza

6
Non chiamare il tuo dizionario dict. La parola "dict" è già una parola chiave in Python. Usa qualcos'altro, come mydict.
Rick supporta Monica il

Nota: questa domanda riguarda l'accesso agli elementi di dict tramite indice , il che non ha senso perché i dict non sono ordinati. Per una domanda sull'accesso agli elementi in un dict annidato, vedere Python - accesso a valori annidati nei dizionari .
Aran-Fey

@ Aran-Fey: le cose non ordinate hanno un ordine intrinseco. Non ordinato! = Nessun ordine.
Jamie Marshall

Risposte:


123

Dato che si tratta di un dizionario vi si accede utilizzando i tasti. Recuperando il dizionario memorizzato in "Apple", procedi come segue:

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

E per sapere quanti di loro sono americani (16), fai in questo modo:

>>> mydict["Apple"]["American"]
'16'

9
Come si può farlo dinamicamente senza conoscere la profondità degli elementi?
Ethan Bierlein

3
Cosa vorresti sapere esattamente? Puoi ottenere le chiavi di un dizionario con in .keys()modo da potervi accedere dinamicamente.
Morten Kristensen

3
Come, ad esempio, se avessi un dizionario di profondità sconosciuta, ad esempio un dizionario annidato, e hai un elemento "n"a una profondità sconosciuta, memorizzato in un elemento sconosciuto.
Ethan Bierlein

1
Questa è una domanda molto ampia. Data la struttura dei dati, dovresti quindi scrivere una funzione o una classe per gestirla in modo appropriato. Forse potresti fornire una chiave e una strategia per cercare di trovare la chiave.
Morten Kristensen

1
@EthanBierlein usa: 'for key, value in dictionary.iteritems ()' per avere accesso sia alla chiave che al valore
danius

25

Se la domanda è, se so di avere un dicts che contiene "Apple" come frutto e "American" come tipo di mela, userei:

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


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

come altri hanno suggerito. Se invece la domanda è, non sai se "Apple" come frutto e "Americano" come tipo di "Apple" esistono quando leggi un file arbitrario nella tua struttura dati dict of dict, potresti fare qualcosa del tipo:

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

o meglio ancora in modo da non iterare inutilmente l'intero dict di dict se sai che solo Apple ha il tipo americano:

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

In tutti questi casi non importa in quale ordine i dizionari memorizzano effettivamente le voci. Se sei davvero preoccupato per l'ordine, potresti prendere in considerazione l'utilizzo di un OrderedDict:

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


20

Come ho notato la tua descrizione, sai solo che il tuo parser ti darà un dizionario che i suoi valori sono anche un dizionario in questo modo:

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

Quindi devi iterare sul dizionario dei tuoi genitori. Se vuoi stampare o accedere a tutte le prime chiavi del dizionario sampleDict.values()nell'elenco, puoi usare qualcosa del genere:

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

Se vuoi accedere solo alla prima chiave del primo elemento sampleDict.values(), questo può essere utile:

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

Se usi l'esempio che hai fornito nella domanda, intendo:

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

L'output per il primo codice è:

American
Indian

E l'output per il secondo codice è:

American

10

Come bonus, vorrei offrire una soluzione diversa al tuo problema. Sembra che tu abbia a che fare con dizionari annidati, il che di solito è noioso, specialmente quando devi verificare l'esistenza di una chiave interna.

Ci sono alcune librerie interessanti su questo argomento su pypi, ecco una rapida ricerca per te.

Nel tuo caso specifico, dict_digger sembra adatto.

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

8

Puoi usare dict['Apple'].keys()[0]per ottenere la prima chiave nel Appledizionario, ma non c'è alcuna garanzia che lo sarà American. L'ordine delle chiavi in ​​un dizionario può cambiare a seconda del contenuto del dizionario e dell'ordine in cui sono state aggiunte le chiavi.


a meno che non usi OrderedDictin collectionsbiblioteca
Escachator

7

So che ha 8 anni, ma sembra che nessuno abbia effettivamente letto e risposto alla domanda.

Puoi chiamare .values ​​() su un dict per ottenere un elenco dei dict interni e quindi accedervi per indice.

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

2
interessante, ho provato questo e ho ottenuto 'dict_values' object does not support indexing . Immagino che questa risposta abbia bisogno di un aggiornamento poiché è necessario avvolgere dict_values ​​per recuperare un elenco
Yuca

1
@ Yucca - Avevi ragione, non ho testato il mio codice. La risposta è stata aggiornata
Jamie Marshall


2

Semplice esempio per capire come accedere agli elementi nel dizionario: -

Crea un dizionario

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

Scopri di più sui dizionari Python e impara in modo interattivo qui ...


1

Poche persone sembrano, nonostante le molte risposte a questa domanda, abbiano sottolineato che i dizionari sono mappature non ordinate, e così (fino alla benedizione dell'ordine di inserzione con Python 3.7) l'idea della "prima" voce in un dizionario è letteralmente fatta senza senso. E anche a è OrderedDictpossibile accedere solo tramite indice numerico utilizzando bruttezze come mydict[mydict.keys()[0]](solo Python 2, poiché in Python 3 keys()è un iteratore non sottoscrivibile.)

Da 3.7 in poi e in pratica anche in 3.6 - il nuovo comportamento è stato introdotto allora, ma non è stato incluso come parte della specifica del linguaggio fino a 3.7 - iterazione sulle chiavi, valori o elementi di un dict (e, credo, un impostato anche) produrrà per primi gli oggetti inseriti meno di recente. Non esiste ancora un modo semplice per accedervi tramite indice numerico di inserimento.

Per quanto riguarda la questione della selezione e della "formattazione" degli elementi, se si conosce la chiave che si desidera recuperare nel dizionario, normalmente la si utilizzerà come pedice per recuperarla ( my_var = mydict['Apple']).

Se vuoi davvero essere in grado di indicizzare gli elementi in base al numero di voce (ignorando il fatto che il numero di una voce particolare cambierà man mano che vengono effettuati gli inserimenti), la struttura appropriata sarebbe probabilmente un elenco di tuple di due elementi. Invece di

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

potresti usare:

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

In questo regime la prima voce è mylist[0]nella classica forma elencata e il suo valore è ('Apple', {'American':'16', 'Mexican':10, 'Chinese':5}). È possibile scorrere l'intero elenco come segue:

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

ma se sai che stai cercando la chiave "Apple", perché non dovresti usare un dict invece?

È possibile introdurre un ulteriore livello di riferimento indiretto memorizzando nella cache l'elenco di chiavi, ma la complessità di mantenere sincronizzate due strutture di dati aumenterebbe inevitabilmente la complessità del codice.


0

Con la seguente piccola funzione, scavare in un dizionario a forma di albero diventa abbastanza 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

Ora, dig(mydict, "Apple.Mexican")ritorna 10, mentre dig(mydict, "Grape")restituisce la sottostruttura {'Arabian':'25','Indian':'20'}. Se una chiave non è contenuta nel dizionario, digrestituisce None.

Nota che puoi facilmente modificare (o anche parametrizzare) il carattere separatore da "." a "/", "|" eccetera.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.