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.