t.unicode('utf-8')的意外行为 - Python

时间:2014-05-07 01:32:13

标签: python json unicode utf-8

我有一个带有几个键的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时,我错过了什么?” 我是否应该删除所有前导和尾随空格(而不是字符串中有任何空格)

2 个答案:

答案 0 :(得分:3)

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字符 - 两个字符)但解析后的结果确实包含换行符:{{1 }}

这就是为什么这个例子:

'\n' in s

可能会打印比for line in file: d = json.loads(line) print(d['key']) 包含的行更多的行。

与utf-8无关。

一般情况下,非原生新行也可能存在问题,例如file,或者u'"\u2028
"' (U+2028 LINE SEPARATOR)等Unicode新行问题。

答案 1 :(得分:1)

对写入的文件执行相同的检查,但在编写之前,要查看标记的值的数量。并确保这些价值观中没有'\\n'。这可能会影响你的数量 有关更多详情,请参见J.F.'s answer below

与您无关的错误说明:

(a)当JSON为loads()时,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']中的任何一个{{1} },None运算符会出错。