Кодировать ключи словарей внутри списка от unicode до ascii

У меня есть образец ответа с списком друзей из facebook:

[{u'uid': 513351886, u'name': u'Mohammed Hossein', u'pic_small': u'http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs643.snc3/27383_513351886_4933_t.jpg'}, {u'uid': 516583220, u'name': u'Sim Salabim', u'pic_small': u'http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs348.snc4/41505_516583220_5681339_t.jpg'}] 

Как я могу проанализировать этот список ключей кодировки словарей на ascii? Я пробовал что-то вроде этого:

 response = simplejson.load(urllib.urlopen(REST_SERVER, data)) for k in response: for id, stuff in k.items(): id.encode("ascii") logging.debug("id: %s" % id) return response 

Но закодированные ключи не сохраняются, и в результате я все равно получаю значения unicode.

Во-первых: вам действительно нужно это делать? Строки находятся в Юникоде по какой-то причине: вы просто не можете представлять все в простой ASCII, что вы можете в Unicode. Это, вероятно, не будет проблемой для ваших словарных клавиш «uid», «name» и «pic_small»; но, вероятно, не будет проблемой оставить их как Unicode. (Библиотека «simplejson» ничего не знает о ваших данных, поэтому использует Unicode для каждой строки – лучше безопасно, чем жаль).

Так или иначе:

В Python строки не могут быть изменены. Метод .encode не изменяет строку; он возвращает новую строку, которая является кодированной версией.

То, что вы хотите сделать, это создать новый словарь, который заменяет ключи закодированными ключами. Мы можем сделать это, передав каждую пару (закодированный ключ, исходное значение) как * args для конструктора dict.

Это выглядит так:

 dict((k.encode('ascii'), v) for (k, v) in original.items()) 

Аналогичным образом, мы можем использовать понимание списка, чтобы применить это к каждому словарю, и создать новый список. (Мы можем изменить список на месте, но этот способ чище.)

 response = simplejson.load(urllib.urlopen(REST_SERVER, data)) # We create the list of modified dictionaries, and re-assign 'response' to it: response = [ dict((k.encode('ascii'), v) for (k, v) in original.items()) # the modified version for original in response # of each original dictionary. ] return response 

Ваши другие ответы намекают на это, но не выходят и говорят это: поиск словаря и сравнение строк в Python прозрачно конвертируют между Unicode и ASCII:

 >>> x = {u'foo':'bar'} # unicode key, ascii value >>> x['foo'] # look up by ascii 'bar' >>> x[u'foo'] # or by unicode 'bar' >>> x['foo'] == u'bar' # ascii value has a unicode equivalent True 

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