10

可能重复:
如何从 Python 中的 JSON 获取字符串对象而不是 Unicode 对象?

作为从 JSON API 调用解析的多级字典,我有很多输入。这些字符串都是 unicode 格式,这意味着有很多u'stuff like this'. 我正在使用jq来处理结果,并且需要将这些结果转换为 ASCII。

我知道我可以编写一个函数来像这样转换它:

def convert(input):
    if isinstance(input, dict):
        ret = {}
        for stuff in input:
            ret = convert(stuff)
    elif isinstance(input, list):
        ret = []
        for i in range(len(input))
            ret = convert(input[i])
    elif isinstance(input, str):
        ret = input.encode('ascii')
    elif :
        ret = input
    return ret

这甚至正确吗?没有把握。不过,这不是我想问你的。

我要问的是,这是该问题的典型暴力解决方案。肯定有更好的办法。一种更pythonic的方式。我不是算法专家,但这个看起来也不是特别快。

那么有没有更好的方法呢?或者如果没有,这个功能可以改进吗...?


回复后编辑

Mark Amery 的回答是正确的,但我想发布它的修改版本。他的函数适用于 Python 2.7+,而我使用的是 2.6,因此必须对其进行转换:

def convert(input):
    if isinstance(input, dict):
        return dict((convert(key), convert(value)) for key, value in input.iteritems())
    elif isinstance(input, list):
        return [convert(element) for element in input]
    elif isinstance(input, unicode):
        return input.encode('utf-8')
    else:
        return input
4

1 回答 1

30

递归似乎是要走的路,但如果你在 python 2.xx 上,你想检查unicode,而不是str(str类型表示字节字符串,类型表示unicodeunicode 字符字符串;两者都不是从另一个继承并且在解释器中显示的是 unicode 类型的字符串,前面有 au)。

您发布的代码中还有一点语法错误(尾随elif:应该是else),并且在输入是字典或列表的情况下,您不会返回相同的结构。(在字典的情况下,您将返回最终键的转换版本;在列表的情况下,您将返回最终元素的转换版本。两者都不对!)

您还可以通过使用推导使您的代码漂亮和 Pythonic。

那么,这里是我推荐的:

def convert(input):
    if isinstance(input, dict):
        return {convert(key): convert(value) for key, value in input.iteritems()}
    elif isinstance(input, list):
        return [convert(element) for element in input]
    elif isinstance(input, unicode):
        return input.encode('utf-8')
    else:
        return input

最后一件事。我encode('ascii')改为encode('utf-8'). 我的推理如下:任何仅包含 ASCII 字符集中字符的 unicode 字符串在以 ASCII 编码时将由与以 utf-8 编码时相同的字节字符串表示,因此使用 utf-8 而不是 ASCII 不能破坏任何东西和只要您处理的 unicode 字符串仅使用 ASCII 字符,更改将不可见。但是,此更改扩展了函数的范围,以便能够处理来自整个 unicode 字符集的字符串,而不仅仅是 ASCII 字符串,如果有必要的话。

于 2012-10-27T16:01:56.393 回答