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 додає цю таблицю unicode? Який найкращий спосіб її видалити?

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

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 '... ПОМИЛКА НА ПИСМУ: Помилка значення (кодук "ascii" не може кодувати символ u '\ xe1' на позиції 5: порядковий номер не в діапазоні (128))
Девід Уррі

@janehouse правильна відповідь тут - відповідь jdi Я дійсно думаю, що ви повинні змінити його.
Декель

Відповіді:


168

Префікс u просто означає, що у вас є рядок Unicode. Якщо ви дійсно використовуєте рядок, він не відображатиметься у ваших даних. Не викидайте друкований вихід.

Наприклад, спробуйте це:

print mail_accounts[0]["i"]

Ви не побачите і


5
Ваш відповідь була найкориснішим один я, і я думаю , що запитувач цього питання було б дійсно оцінили його: stackoverflow.com/questions/956867 / ...
jimh

1
Дуже дякую !
Мене

За винятком випадків, коли ви копіюєте і вставляєте їх, uу ваших даних є величезна кількість s. Відверто кажучи, роздруківка а, uщоб вказати, що це рядок Unicode, - одна з найгірших помилок щодо Python. Дуже смішно. Чому б не надрукувати aперед кожним рядком, якщо це ASCII? iЯкщо це ціле число?
Snowcrash

У Python 2 рядки Unicode мають інший тип, ніж рядки байтів, тому репр даних містить префікс для цього. Справа не в тому, яким буде зміст, а про тип. Префікс u - це добре, якщо ви вставляєте вміст назад в програму Python. Якщо ні, можливо, ви хочете замість цього використовувати json.dumps ().
Нед Батчелдер

Ви повинні використовувати рядок для пошуку словника json. однак ви не можете використовувати оператор крапки.
Мадоки

151

Все круто, чоловіче. Значення 'u' є хорошою справою, воно вказує, що рядок типу Unicode в python 2.x.

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


71
Мені подобається дуже холодний тон цього. +1 за (правильну) відповідь, яка змусила мене посміхнутися.
mgilson

19
Просто, холод ... (┛◉Д◉) ┛ 彡 ┻━┻
fulvio

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перетворює дікт назад у рядок (закодований JSON). Це не те, що хотіла зробити ОП. -1.
Марк Амері

10
Але якщо ви використовуєте його разом з json.loads, він виводить словник без закодованих символів, це відповідь на питання (це друк d3 вище), добре прочитайте відповідь!
Меркурій

8

У uпрефікс означає , що ці рядки Юнікод , а не 8-бітові рядки. Найкращий спосіб не показувати uпрефікс - перейти на Python 3, де рядки за замовчуванням є unicode. Якщо це не варіант, 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

"кодування визначає кодування, яке використовується для інтерпретації будь-яких об'єктів str, декодованих цим екземпляром (UTF-8 за замовчуванням)."


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символ - справжня неприємність, коли ви хочете скопіювати текст і вставити його кудись у свій код.

Як всі вам скажуть, це тому, що це представлення Unicode, і це може виходити з того, що ви раніше використовували дані 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")


Відповідь без будь-яких пояснень майже марний. Спробуйте додати інформацію, наприклад, чому це допоможе.
Абхілаш Чандран

Особисто я вважаю тривалими відповідями із занадто великою кількістю непотрібної інформації. Наведені вище відповіді вже пояснюють, що значення є unicode і його потрібно перетворити на ascii, тому я не повторюю все це. Просто показаний простіший спосіб отримати значення. Якщо у когось є проблеми з використанням цієї відповіді, просто запитайте, і я рада пояснити далі! Спасибі
2-а лабораторія

Це насправді єдина відповідь, яка стисло показує, як перекодувати кожен рядок до "нормального", не проходячи (що має бути смішно неефективним) циклом json.loads, json.dumps.
Ед Рендалл

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.