【问题标题】:Unexpected behaviour of t.unicode('utf-8') - Pythont.unicode('utf-8') 的意外行为 - Python
【发布时间】:2014-06-23 19:21:51
【问题描述】:

我有一个带有几个键的 json 文件。我想使用其中一个键并将该字符串写入文件。该字符串最初是 unicode。所以,我愿意,s.unicode('utf-8')

现在,该 json 中有另一个键,我将其写入另一个文件(这是一项机器学习任务,正在将原始字符串写入一个,将特征写入另一个)。问题是,最后,带有 unicode 字符串的文件有更多的行数(当使用“wc -l”计算时),这误导了我的工具,它崩溃说大小不一样。

参考代码:

for line in input_file:
                j = json.loads(line)
                text = j['text']
                label = j[t]

                output_file.write(str(label) + '\t' + text.encode('utf-8') + '\n')
                norm_file.write(j['normalized'].encode('utf-8') + '\n')

使用“wc -l”时的区别

16862965

这是我期望的行数,我得到的是

16878681

实际上更高。所以我写了一个脚本来看看实际上有多少输出标签

with open(sys.argv[1]) as input_file:
        for line in input_file:
                p = line.split('\t')
                if p[0] not in ("good", "bad"):
                   print p
                else:
                   c += 1


print c

而且,你瞧,我有16862965 行,这意味着有些是错误的。我把它们打印出来,我得到一堆空的换行符('\n')。所以我想我的问题是,“在处理这样的 unicode 时我错过了什么?” 我应该去掉所有前导和尾随空格(不是字符串中有任何空格)

【问题讨论】:

    标签: python json unicode utf-8


    【解决方案1】:

    在写入文件之前执行与写入文件相同的检查,以查看标记了多少值。并确保这些值中没有'\\n'。这可能会影响您的计数。
    如需了解更多详情,请参阅J.F.'s answer below

    与您的错误无关的注释:

    (a) 当 JSON 为 loads()ed 时,str 对象已自动为 unicode:

    >>> a = '{"b":1}'
    >>> json.loads(a)['b']
    1
    >>> json.loads(a).keys()
    [u'b']
    >>> type(json.loads(a).keys()[0])
    <type 'unicode'>
    

    所以文件写入中的str(label) 应该只是labelunicode(label)。将 textj['normalized'] 写入文件时,您不需要对它们进行编码。相反,当你打开它时,set the file encoding to 'utf-8'

    (b) 顺便说一句,在写入操作中使用format()join() - 如果labeltextj['normalized'] 中的任何一个是None+ 运算符将给出错误。

    【讨论】:

    • 感谢您的提示。问题实际上出在数据上。不知道为什么有些日志中有一堆“\n”。但这有助于使代码更好!在编写打印语句时,我一直在使用 .format() 。太整齐了
    • 请注意,@j-f-sebastian 下面的回答涵盖了错误的更多实际原因。处理同一件事的几个 SO 问题:herehere;和google
    【解决方案2】:

    JSON 字符串中不能包含文字换行符,例如,

    not_a_json_string = '"\n"' # in Python source
    json.loads(not_a_json_string) # raises ValueError
    

    但它们可以包含转义的换行符:

    json_string = r'"\n"' # raw-string literal (== '"\\n"')
    s = json.loads(json_string) 
    

    即,原始文本 (json_string) 中没有换行符(它有反斜杠后跟 n 字符 -- 两个字符),但解析结果确实包含换行符:'\n' in s

    这就是示例的原因:

    for line in file:
        d = json.loads(line)
        print(d['key'])
    

    可能会打印比file 包含的更多行。

    与 utf-8 无关。

    一般来说,非本地换行也可能存在问题,例如 b'\r\r\n\n',或 Unicode 换行问题,例如 u'"\u2028
"' (U+2028 LINE SEPARATOR)

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-05
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    • 2011-11-24
    • 1970-01-01
    相关资源
    最近更新 更多