6 Stimmen

KeyError beim Erstellen eines mehrdimensionalen Wörterbuchs in Python

Ich versuche, ein Wörterbuch mit zwei Schlüsseln zu erstellen, erhalte aber beim Zuweisen von Elementen einen KeyError. Ich bekomme den Fehler nicht, wenn ich jeden der Schlüssel einzeln verwende, und die Syntax scheint ziemlich einfach zu sein, also bin ich ratlos.

searchIndices = ['Books', 'DVD']
allProducts = {}
for index in searchIndices:
    res = amazon.ItemSearch(Keywords = entity, SearchIndex = index, ResponseGroup = 'Large', ItemPage = 1, Sort = "salesrank", Version = '2010-11-01')
    products = feedparser.parse(res)
    for x in range(10):
        allProducts[index][x] = { 'price' : products['entries'][x]['formattedprice'],  
                                  'url'   : products['entries'][x]['detailpageurl'], 
                                  'title' : products['entries'][x]['title'], 
                                  'img'   : products['entries'][x]['href'],
                                  'rank'  : products['entries'][x]['salesrank'] 
                                }

Ich glaube nicht, dass das Problem mit dem Feedparser (der xml in dict umwandelt) oder mit den Ergebnissen, die ich von amazon erhalte, zusammenhängt, da ich keine Probleme habe, ein dict zu erstellen, wenn ich entweder 'allProducts[x]' oder 'allProducts[index]' verwende, aber nicht beide.

Was übersehe ich?

8voto

Cameron Punkte 91138

Für die Zuordnung zu allProducts[index][x] wird zunächst eine Abfrage durchgeführt nach allProducts[index] um ein Diktat zu erhalten, dann wird der Wert, den Sie zuweisen, unter dem Index x in diesem Diktat.

Beim ersten Durchgang durch die Schleife jedoch, allProducts[index] gibt es noch nicht. Versuchen Sie dies:

for x in range(10):
    if index not in allProducts:
        allProducts[index] = {  }    # or dict() if you prefer
    allProducts[index][x] = ...

Da Sie alle Indizes kennen, die in allProducts im Voraus zu initialisieren, können Sie es stattdessen wie folgt initialisieren:

map(lambda i: allProducts[i] = {  }, searchIndices)
for index in searchIndices:
    # ... rest of loop does not need to be modified

4voto

ncoghlan Punkte 37564

Wenn Sie Python 2.5 oder höher verwenden, dann ist diese Art von Situation wie geschaffen für collections.defaultdict .

Ersetzen Sie einfach die Leitung:

allProducts = {}

Mit den folgenden:

import collections
allProducts = collections.defaultdict(dict)

Ein Beispiel für die Anwendung dieser Methode:

>>> import collections
>>> searchIndices = ['Books', 'DVD']
>>> allProducts = collections.defaultdict(dict)
>>> for idx in searchIndices:
...   print idx, allProducts[idx]
...
Books {}
DVD {}

1voto

pkit Punkte 7583

Sie können die setdefault Methode des Wörterbuchs.

for x in range(10):
        allProducts.setdefault(index, {})[x] = ...

0voto

chmullig Punkte 12716

Sie müssen Python mitteilen, dass es sich um ein dict innerhalb eines dicts handelt. Er hat keine Ahnung, dass allProducts[index] ein anderes Wörterbuch sein sollte.

Sie müssen Zeilen wie diese hinzufügen, wenn Sie dies tun wollen (oder ein Standarddict verwenden):

allProducts = {}
for index in searchIndices:
    allProducts[index] = {}

0voto

Paulo Scardine Punkte 67246
searchIndices = ['Books', 'DVD']
allProducts = {}
for index in searchIndices:
    res = amazon.ItemSearch(Keywords = entity, SearchIndex = index, ResponseGroup = 'Large', ItemPage = 1, Sort = "salesrank", Version = '2010-11-01')
    products = feedparser.parse(res)
    for x in range(10):
        if not allProducts.has_key(index):
            allProducts[index] = {}
        allProducts[index][x] = { 'price' : products['entries'][x]['formattedprice'],  
                                  'url'   : products['entries'][x]['detailpageurl'], 
                                  'title' : products['entries'][x]['title'], 
                                  'img'   : products['entries'][x]['href'],
                                  'rank'  : products['entries'][x]['salesrank'] 
                                }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X