KeyError при построении многомерного словаря в Python - PullRequest
4 голосов
/ 08 февраля 2011

Я пытаюсь создать словарь с двумя ключами, но получаю KeyError при назначении элементов. Я не получаю сообщение об ошибке при использовании каждого из ключей по отдельности, и синтаксис кажется довольно простым, поэтому я в замешательстве.

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

Я не верю, что проблема заключается в feedparser (который преобразует xml в dict) или в результаты, которые я получаю от amazon, поскольку у меня нет проблем с созданием dict при использовании «allProducts [x]» или allProducts [index] ', но не оба.

Чего мне не хватает?

Ответы [ 5 ]

6 голосов
/ 08 февраля 2011

Чтобы присвоить allProducts[index][x], сначала выполняется поиск на allProducts[index] для получения диктата, затем назначаемое вами значение сохраняется в индексе x в этом диктанте.

Однако в первый раз в цикле allProducts[index] еще не существует.Попробуйте это:

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

Поскольку вы знаете все индексы, которые должны быть в allProducts заранее, вы можете вместо этого инициализировать его перед раздачей:

map(lambda i: allProducts[i] = {  }, searchIndices)
for index in searchIndices:
    # ... rest of loop does not need to be modified
3 голосов
/ 08 февраля 2011

Если вы используете Python 2.5 или более позднюю версию, то такая ситуация специально разработана для collections.defaultdict.

Просто замените строку:

allProducts = {}

следующим:

import collections
allProducts = collections.defaultdict(dict)

Пример использования:

>>> import collections
>>> searchIndices = ['Books', 'DVD']
>>> allProducts = collections.defaultdict(dict)
>>> for idx in searchIndices:
...   print idx, allProducts[idx]
...
Books {}
DVD {}
1 голос
/ 08 февраля 2011

Вы можете использовать setdefault метод словаря.

for x in range(10):
        allProducts.setdefault(index, {})[x] = ...
0 голосов
/ 08 февраля 2011
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'] 
                                }
0 голосов
/ 08 февраля 2011

Вы должны сказать python, что это диктат внутри диктата. Он понятия не имеет, что allProducts [index] должен быть другим словарем.

Вам нужно добавлять такие строки, когда вы пытаетесь это сделать (или использовать defaultdict):

allProducts = {}
for index in searchIndices:
    allProducts[index] = {}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...