Python: json.loads возвращает элементы с префиксом 'u'

161

Я получу JSON-кодированную строку Obj-C, и я декодирую фиктивную строку (пока), как показано ниже. Мой вывод выходит с символом 'u', префиксом каждого элемента:

[{u'i': u'imap.gmail.com', u'p': u'aaaa'}, {u'i': u'333imap.com', u'p': u'bbbb'}...

Как JSON добавляет этот юникод-символ? Какой лучший способ удалить это?

mail_accounts = []
da = {}
try:
    s = '[{"i":"imap.gmail.com","p":"aaaa"},{"i":"imap.aol.com","p":"bbbb"},{"i":"333imap.com","p":"ccccc"},{"i":"444ap.gmail.com","p":"ddddd"},{"i":"555imap.gmail.com","p":"eee"}]'
    jdata = json.loads(s)
    for d in jdata:
        for key, value in d.iteritems():
            if key not in da:
                da[key] = value
            else:
                da = {}
                da[key] = value
        mail_accounts.append(da)
except Exception, err:
    sys.stderr.write('Exception Error: %s' % str(err))

print mail_accounts
janeh
источник
7
У Python есть проблема здесь. Все не холодно. Я получаю ошибки в строках, которые создает Python, когда я пытаюсь записать эти строки в файл. Например, когда python берет "53" из JSON, он превращает его в u'53 'и пытается записать его в файл в виде шестнадцатеричного символа u' \ xe1 ', что заставляет Python взять очень хорошую строку и рвать ее: JSON: {"sa_BstDeAv": "53", "sa_BwVUpMx" ... PYTHON: {u'sa_BstDeAv ': u'53', u'sa_BwVUpMx '... ERROR ON WRITE: Ошибка значения (кодек' ascii 'не может кодировать символ u '\ xe1' в позиции 5: порядковый номер не в диапазоне (128))
Дэвид Урри
@ janehouse правильный ответ здесь - это ответ от jdi. Я действительно думаю, что вы должны изменить его.
Декель

Ответы:

168

Префикс u означает, что у вас есть строка Unicode. Когда вы действительно используете строку, она не появится в ваших данных. Не поддавайтесь распечатке.

Например, попробуйте это:

print mail_accounts[0]["i"]

Вы не увидите вас.

Нед Бэтчелдер
источник
5
Ваш ответ был самым полезным, который я получил, и я думаю, что тот, кто задает этот вопрос, действительно оценил бы его: stackoverflow.com/questions/956867/…
jimh
1
Спасибо вам большое ! я был смущен для тебя '' письмо так долго
кетан хандагале
За исключением случаев, когда вы копируете и вставляете это, у вас есть огромное количество us в ваших данных. Честно говоря, распечатка, uуказывающая, что это строка в Юникоде, является одной из худших ошибок в Python. Совершенно нелепо Почему бы не печатать aперед каждой строкой, если это ASCII? А iесли это целое число?
Снегопад
В Python 2 строки Unicode имеют тип, отличный от байтовых строк, поэтому в repr данных включен префикс для указания этого. Дело не в том, что такое содержимое, а в типе. Префикс u подходит, если вы вставляете содержимое обратно в программу Python. Если нет, возможно, вы хотите использовать json.dumps () вместо этого.
Нед Бэтчелдер
Вы должны использовать строку для поиска в словаре JSON. однако вы не можете использовать оператор точки.
Мэддокс
151

Все круто, чувак. 'U' - хорошая вещь, это означает, что строка имеет тип Unicode в python 2.x.

http://docs.python.org/2/howto/unicode.html#the-unicode-type

Мужчина
источник
71
Мне нравится очень холодный тон этого. +1 за (правильный) ответ, который заставил меня улыбнуться.
Мгилсон
19
Просто, расслабься ... (┛◉Д◉) ┛ 彡 ┻━┻
фулвио
31
Это был самый расслабляющий ответ, который я читал на StackOverflow.
aanrv
3
☮ ☮ ☮ Мир ☮ ☮ ☮
sr9yar
54

d3Ниже печать является тот , который вы ищете (это сочетание свалок и нагрузок) :)

Наличие:

import json

d = """{"Aa": 1, "BB": "blabla", "cc": "False"}"""

d1 = json.loads(d)              # Produces a dictionary out of the given string
d2 = json.dumps(d)              # Produces a string out of a given dict or string
d3 = json.dumps(json.loads(d))  # 'dumps' gets the dict from 'loads' this time

print "d1:  " + str(d1)
print "d2:  " + d2
print "d3:  " + d3

Печать:

d1:  {u'Aa': 1, u'cc': u'False', u'BB': u'blabla'}
d2:  "{\"Aa\": 1, \"BB\": \"blabla\", \"cc\": \"False\"}"
d3:  {"Aa": 1, "cc": "False", "BB": "blabla"}
Меркурий
источник
3
А? json.dumpsпреобразует dict обратно в (JSON-кодированную) строку. Это не то, что хотел сделать ОП. -1.
Марк Амери
10
Но если вы используете его вместе с json.loads, он выводит словарь без закодированных символов, который является ответом на вопрос (это печать d3 выше), прочитайте ответ хорошо!
Меркурий
8

В uпрефиксе означает , что эти строки Юникод , а не 8-битовые строки. Лучший способ не показывать uпрефикс - это переключиться на Python 3, где строки по умолчанию имеют юникод. Если это не вариант, strконструктор преобразует Unicode в 8-битный код, поэтому просто рекурсивно зацикливайте результат и преобразуйте unicodeв str. Однако, вероятно, лучше всего оставить строки как Unicode.

Абе Карплус
источник
8

Unicode является подходящим типом здесь. Документы JSONDecoder описывают таблицу преобразования и указывают, что строковые объекты json декодируются в объекты Unicode

https://docs.python.org/2/library/json.html#encoders-and-decoders

JSON                    Python
==================================
object                  dict
array                   list
string                  unicode
number (int)            int, long
number (real)           float
true                    True
false                   False
null                    None

msgstr "кодировка определяет кодировку, используемую для интерпретации любых str-объектов, декодированных этим экземпляром (UTF-8 по умолчанию)."

JDI
источник
7

Эти символы 'u', добавляемые к объекту, означают, что объект закодирован в "Unicode".

Если вы хотите удалить эти символы 'u' из вашего объекта, вы можете сделать это:

import json, ast
jdata = ast.literal_eval(json.dumps(jdata)) # Removing uni-code chars

Давайте извлекать из оболочки Python

>>> import json, ast
>>> jdata = [{u'i': u'imap.gmail.com', u'p': u'aaaa'}, {u'i': u'333imap.com', u'p': u'bbbb'}]
>>> jdata = ast.literal_eval(json.dumps(jdata))
>>> jdata
[{'i': 'imap.gmail.com', 'p': 'aaaa'}, {'i': '333imap.com', 'p': 'bbbb'}]
Нивеш Кришна
источник
Я предлагаю каждому новичку просто попробовать этот сценарий и вуаля, у вас есть сценарий для преобразования ~ из вывода ~ u'JSON :) ... если можно добавить только stdin в сценарий и формат json в конце, вы готов идти!
Джордан Джи
4

Я продолжал сталкиваться с этой проблемой при попытке записать данные JSON в журнал с loggingбиблиотекой Python для целей отладки и устранения неполадок. Получение uсимвола - это настоящая неприятность, когда вы хотите скопировать текст и вставить его в свой код где-нибудь.

Как все скажут вам, это потому, что это представление в Юникоде, и это может быть связано с тем, что вы использовали json.loads()для загрузки данных из строки в первую очередь.

Если вам нужно представление JSON в журнале без uпрефикса, нужно использовать хитрость json.dumps()перед выходом из системы. Например:

import json
import logging

# Prepare the data
json_data = json.loads('{"key": "value"}')

# Log normally and get the Unicode indicator
logging.warning('data: {}'.format(json_data))
>>> WARNING:root:data: {u'key': u'value'}

# Dump to a string before logging and get clean output!
logging.warning('data: {}'.format(json.dumps(json_data)))
>>> WARNING:root:data: {'key': 'value'}
Йонатан
источник
1
Это действительно должен быть лучший ответ, во многих случаях вы абсолютно не «просто лишены». Спасибо тебе большое за это!
Джессика Пеннелл
1

Попробуй это:

mail_accounts [0] .encode ( "ASCII")

2nd Sight Lab
источник
Ответ без объяснения почти бесполезен. Пожалуйста, попробуйте добавить информацию, например, почему это поможет.
Абхилаш Чандран
Лично я нахожу длинные ответы, отвлекающие слишком много ненужной информации. Приведенные выше ответы уже объясняют, что значение является Unicode и должно быть преобразовано в ASCII, поэтому я не повторяю все это. Просто показываю более простой способ получить значение. Если у кого-то есть проблемы с использованием этого ответа, просто спросите, и я с удовольствием объясню дальше! Спасибо
2-й Sight Lab
На самом деле это единственный ответ, в котором кратко показано, как перекодировать каждую строку в «нормальную», не проходя (что должно быть смехотворно неэффективно) цикл json.loads, json.dumps.
Эд Рэндалл
0

Просто замените u 'одинарной кавычкой ...

print (str.replace(mail_accounts,"u'","'"))
Mikematic
источник