Zugriff auf Elemente des Python-Wörterbuchs über den Index

117

Betrachten Sie ein Dikt wie

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

Wie greife ich beispielsweise auf ein bestimmtes Element dieses Wörterbuchs zu? Zum Beispiel möchte ich das erste Element nach einer Formatierung des ersten Elements von Apple drucken, das in unserem Fall nur "amerikanisch" ist.

Zusätzliche Informationen Die obige Datenstruktur wurde durch Parsen einer Eingabedatei in einer Python-Funktion erstellt. Einmal erstellt, bleibt es jedoch für diesen Lauf gleich.

Ich benutze diese Datenstruktur in meiner Funktion.

Wenn sich die Datei ändert, ist der Inhalt der Datei beim nächsten Ausführen dieser Anwendung unterschiedlich, und daher ist der Inhalt dieser Datenstruktur unterschiedlich, aber das Format ist dasselbe. Sie sehen also, ich weiß in meiner Funktion nicht, dass das erste Element in Apple "amerikanisch" oder etwas anderes ist, daher kann ich "amerikanisch" nicht direkt als Schlüssel verwenden.

Alessandra
quelle
2
Können Sie bitte ein Beispiel für die erwartete Ausgabe geben?
Björn Pollex
3
Was möchten Sie eigentlich mit dieser Struktur machen? Und kennen Sie die Schlüssel des Diktats (in Ihrem Beispiel "Apfel" und "Trauben")? Oder wissen Sie nur, dass Sie ein Diktat von Diktaten bekommen?
Juanchopanza
6
Rufen Sie Ihr Wörterbuch nicht an dict. Das Wort 'dict' ist in Python bereits ein Schlüsselwort. Verwenden Sie etwas anderes, wie mydict.
Rick unterstützt Monica
Hinweis: Bei dieser Frage geht es um den Zugriff auf Diktatelemente über den Index. Dies ist nicht sinnvoll, da Diktate ungeordnet sind. Eine Frage zum Zugriff auf Elemente in einem verschachtelten Diktat finden Sie unter Python - Zugreifen auf Werte, die in Wörterbüchern verschachtelt sind .
Aran-Fey
@ Aran-Fey: Ungeordnete Dinge haben eine innere Ordnung. Unbestellt! = Keine Bestellung.
Jamie Marshall

Antworten:

122

Da es sich um ein Wörterbuch handelt, greifen Sie mit den Schlüsseln darauf zu. Gehen Sie wie folgt vor, um das Wörterbuch unter "Apple" zu speichern:

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

Und wenn Sie wissen, wie viele von ihnen Amerikaner sind (16), gehen Sie folgendermaßen vor:

>>> mydict["Apple"]["American"]
'16'
Morten Kristensen
quelle
9
Wie könnte man dies dynamisch tun, ohne die Tiefe der Elemente zu kennen?
Ethan Bierlein
3
Was genau möchten Sie wissen? Sie können die Schlüssel eines Wörterbuchs mit .keys()abrufen, um dynamisch darauf zugreifen zu können.
Morten Kristensen
3
Zum Beispiel, wenn Sie ein Wörterbuch mit unbekannter Tiefe hatten, z. B. ein verschachteltes Wörterbuch, und ein Element "n"in unbekannter Tiefe in einem unbekannten Element gespeichert haben.
Ethan Bierlein
1
Das ist eine sehr breite Frage. In Anbetracht Ihrer Datenstruktur würden Sie dann eine Funktion oder Klasse schreiben, um sie entsprechend zu behandeln. Vielleicht könnten Sie einen Schlüssel und eine Strategie für den Versuch, den Schlüssel zu finden, angeben.
Morten Kristensen
1
@EthanBierlein verwenden: 'für Schlüssel, Wert in dictionary.iteritems ()', um Zugriff auf Schlüssel und Wert zu haben
danius
25

Wenn die Fragen lauten: Wenn ich weiß, dass ich ein Diktat von Diktaten habe, das "Apfel" als Frucht und "Amerikaner" als Apfelsorte enthält, würde ich Folgendes verwenden:

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


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

wie andere vorgeschlagen haben. Wenn stattdessen die Frage lautet, ob Sie nicht wissen, ob "Apple" als Frucht und "Amerikaner" als eine Art "Apple" existieren, wenn Sie eine beliebige Datei in Ihr Diktat der Diktatdatenstruktur einlesen, können Sie Folgendes tun:

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

oder noch besser, damit Sie nicht unnötig über das gesamte Diktat von Diktaten iterieren, wenn Sie wissen, dass nur Apple den Typ Amerikaner hat:

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

In all diesen Fällen spielt es keine Rolle, in welcher Reihenfolge die Wörterbücher die Einträge tatsächlich speichern. Wenn Sie wirklich besorgt über die Bestellung sind, können Sie Folgendes in Betracht ziehen OrderedDict:

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

JoshAdel
quelle
20

Wie ich bei Ihrer Beschreibung bemerkt habe, wissen Sie nur, dass Ihr Parser Ihnen ein Wörterbuch gibt, dessen Werte ebenfalls wie folgt lauten:

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

Sie müssen also über Ihr übergeordnetes Wörterbuch iterieren. Wenn Sie alle ersten Wörterbuchschlüssel in der sampleDict.values()Liste ausdrucken oder darauf zugreifen möchten , können Sie Folgendes verwenden:

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

Wenn Sie nur auf den ersten Schlüssel des ersten Elements in zugreifen möchten sampleDict.values(), kann dies nützlich sein:

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

Wenn Sie das Beispiel verwenden, das Sie in der Frage gegeben haben, meine ich:

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

Die Ausgabe für den ersten Code lautet:

American
Indian

Und die Ausgabe für den zweiten Code lautet:

American
Zeinab Abbasimazar
quelle
10

Als Bonus möchte ich eine andere Lösung für Ihr Problem anbieten. Sie scheinen es mit verschachtelten Wörterbüchern zu tun zu haben, was normalerweise mühsam ist, insbesondere wenn Sie prüfen müssen, ob ein innerer Schlüssel vorhanden ist.

Es gibt einige interessante Bibliotheken zu diesem Thema auf pypi, hier ist eine schnelle Suche für Sie.

In Ihrem speziellen Fall scheint dict_digger geeignet zu sein.

>>> 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
Flavian Hautbois
quelle
8

Sie können dict['Apple'].keys()[0]den ersten Schlüssel im AppleWörterbuch abrufen, es gibt jedoch keine Garantie dafür American. Die Reihenfolge der Schlüssel in einem Wörterbuch kann sich abhängig vom Inhalt des Wörterbuchs und der Reihenfolge ändern, in der die Schlüssel hinzugefügt wurden.

Gabe
quelle
es sei denn, Sie verwenden OrderedDictin der collectionsBibliothek
Escachator
7

Ich weiß, dass dies 8 Jahre alt ist, aber niemand scheint die Frage tatsächlich gelesen und beantwortet zu haben.

Sie können .values ​​() für ein Diktat aufrufen, um eine Liste der inneren Diktate abzurufen und somit über den Index darauf zuzugreifen.

>>> 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
quelle
2
Interessant, ich habe es versucht und bekommen 'dict_values' object does not support indexing . Vermutlich muss diese Antwort aktualisiert werden, da Sie dict_values ​​umbrechen müssen, um eine Liste wiederherzustellen
Yuca
1
@ Yucca - Du hattest Recht, ich habe meinen Code nicht getestet. Die Antwort wurde aktualisiert
Jamie Marshall
2

Einfaches Beispiel, um zu verstehen, wie auf Elemente im Wörterbuch zugegriffen wird: -

Erstellen Sie ein Wörterbuch

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

Erfahren Sie mehr über Python-Wörterbücher und lernen Sie hier interaktiv ...

Manish Methani
quelle
0

Trotz der vielen Antworten auf diese Frage scheinen nur wenige Menschen darauf hingewiesen zu haben, dass Wörterbücher ungeordnete Zuordnungen sind, und so (bis zum Segen der Einfügereihenfolge mit Python 3.7) wurde die Idee des "ersten" Eintrags in einem Wörterbuch buchstäblich gemacht keinen Sinn. Und selbst auf einen OrderedDictkann nur über einen numerischen Index zugegriffen werden, wenn solche Hässlichkeiten wie mydict[mydict.keys()[0]](nur Python 2, da Python 3 keys()ein nicht abonnierbarer Iterator ist) verwendet werden.

Ab 3.7 und in der Praxis auch in 3.6 - das neue Verhalten wurde dann eingeführt, aber erst ab 3.7 in die Sprachspezifikation aufgenommen - Iteration über die Schlüssel, Werte oder Elemente eines Diktats (und, glaube ich, a set also) liefert zuerst die zuletzt eingefügten Objekte. Es gibt immer noch keine einfache Möglichkeit, über einen numerischen Einfügeindex auf sie zuzugreifen.

Wenn Sie den Schlüssel kennen, den Sie im Wörterbuch abrufen möchten, verwenden Sie den Schlüssel normalerweise als Index, um ihn abzurufen ( my_var = mydict['Apple']).

Wenn Sie wirklich in der Lage sein möchten, die Elemente nach Eintragsnummer zu indizieren (ohne die Tatsache zu berücksichtigen, dass sich die Nummer eines bestimmten Eintrags beim Einfügen ändert), ist die entsprechende Struktur wahrscheinlich eine Liste von Tupeln mit zwei Elementen. Anstatt

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

Sie könnten verwenden:

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

Unter diesem Regime ist der erste Eintrag mylist[0]in klassischer Listen-endexierter Form und sein Wert ist ('Apple', {'American':'16', 'Mexican':10, 'Chinese':5}). Sie können die gesamte Liste wie folgt durchlaufen:

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

Aber wenn Sie wissen, dass Sie nach dem Schlüssel "Apple" suchen, warum würden Sie nicht stattdessen einfach ein Diktat verwenden?

Sie könnten eine zusätzliche Indirektionsebene einführen, indem Sie die Liste der Schlüssel zwischenspeichern. Die Komplexität, zwei Datenstrukturen synchron zu halten, würde jedoch unweigerlich zur Komplexität Ihres Codes beitragen.

holdenweb
quelle
0

Mit der folgenden kleinen Funktion wird das Durchsuchen eines baumförmigen Wörterbuchs ganz einfach:

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

Kehrt jetzt dig(mydict, "Apple.Mexican")zurück 10, während dig(mydict, "Grape")der Teilbaum erhalten wird {'Arabian':'25','Indian':'20'}. Wenn ein Schlüssel nicht im Wörterbuch enthalten ist, wird digzurückgegeben None.

Beachten Sie, dass Sie das Trennzeichen von '.' Einfach ändern (oder sogar parametrisieren) können. zu '/', '|' etc.

Heinrich unterstützt Monica
quelle