2011-02-07 2 views
3

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

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, когда либо с помощью «allProducts [х ] 'или' allProducts [index] ', но не оба.

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

ответ

5

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

Однако в первый раз по петле 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 
+0

Красивыми, я новичок в Python и забыть что он не автовивит. Зарегистрироватся и поддержит вас, спасибо! – kasceled

+0

@tippytop: Спасибо, рад помочь (вы можете щелкнуть по галочке над подсчетом голосов, чтобы отметить мой ответ, как принято). Поскольку вы новичок в Python (вы говорите как программист Perl ;-)), вы можете не знать, что разница между 'range' и' xrange' - 'range' создает список всех чисел (в памяти), тогда как 'xrange' создает итератор, который генерирует числа один за другим. В этом случае 'range' в порядке, так как вы создаете только небольшой список, но обычно предпочитаете' xrange'. – Cameron

0

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

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

allProducts = {} 
for index in searchIndices: 
    allProducts[index] = {} 
0
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'] 
           } 
1

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

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

Если вы используете 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 {} 
Смежные вопросы