Кодировать ключи словарей внутри списка от юникода до ascii - PullRequest
4 голосов
/ 29 ноября 2010

У меня есть пример ответа со списком друзей из 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.

Ответы [ 2 ]

10 голосов
/ 29 ноября 2010

Во-первых: вам действительно нужно , чтобы сделать это?Строки приведены в 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
5 голосов
/ 29 ноября 2010

Ваши другие ответы намекают на это, но не выходят и не говорят этого: поиск по словарю и сравнение строк в 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...