Python:json.loads返回以“ u”为前缀的项目


161

我将收到来自Obj-C的JSON编码字符串,并且正在解码一个伪字符串(目前),如下面的代码。我的输出结果是在每个项目前加上字符'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从JSON中获取“ 53”时,它将其转换为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))
David Urry

@janehouse正确的答案是jdi的答案,我真的认为您应该更改它。
德克尔

Answers:


167

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字符串与字节字符串的类型不同,因此数据的repr包括表示该前缀的前缀。这与内容的内容无关,而与类型有关。如果将内容粘贴回Python程序,则u前缀很好。如果不是,也许您想使用json.dumps()代替。
Ned Batchelder

您必须使用字符串来搜索json的字典。但是,您可能不使用点运算符。
Maddocks


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编码)字符串。这不是OP想要做的。-1。
Mark Amery

10
但是,如果将它与json.loads一起使用,它将输出不带编码字符的字典,这是问题的答案(上面是d3打印),请仔细阅读答案!
水星

8

u前缀意思是,那些字符串是unicode的,而不是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

“ encoding确定用于解释此实例解码的任何str对象的编码(默认为UTF-8)。”


7

那些附加在对象上的“ u”字符表示该对象以“ unicode”编码。

如果要从对象中删除那些“ u”字符,可以执行以下操作:

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

让我们从python shell签出

>>> 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'}]

我建议每个新手都只需尝试一下此脚本,瞧,您就有一个脚本可以将〜from〜u'JSON输出转换为:) ...如果只能将stdin添加到脚本中,并在末尾添加json格式,则准备好出发!
Jordan Gee

4

当尝试使用Python logging库捕获日志中的JSON数据时,为了调试和故障排除,我一直遇到这个问题。u当您想要复制文本并将其粘贴到代码中的某个位置时,获取字符确实是个麻烦。

就像大家都会告诉你的那样,这是因为它是Unicode表示,它可能来自于您一开始就习惯json.loads()从字符串中加载数据的事实。

如果要在日志中使用不带u前缀的JSON表示形式,诀窍是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
这确实是最好的答案,在很多情况下,'u'绝对不会“被剥夺”。非常感谢你做的这些!
杰西卡·佩内尔

1

试试这个:

mail_accounts [0] .encode(“ ascii”)


没有任何解释的答案几乎是没有用的。请尝试添加一些信息,例如为什么这样做会有帮助。
Abhilash Chandran

就我个人而言,我发现冗长的答案,而且过多的不必要的信息分散了人们的注意力。上面的答案已经说明了该值是unicode,需要将其转换为ascii,因此我不再赘述。只是显示了一种获取价值的简单方法。如果有人在使用此答案时遇到问题,请询问,我很乐意进一步解释!谢谢
2nd Sight Lab

实际上,这是唯一简洁地显示出如何将每个字符串重新编码为“正常”而不经历json.loads,json.dumps循环的过程(必须是效率低下)。
Ed Randall

0

只需用单引号替换u ...

print (str.replace(mail_accounts,"u'","'"))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.