python 何时编码、何时解码?

标签 python python-2.7 encoding

当我应该编码或当我解码时,我总是很困惑。

我所理解的是,当读取以 utf8 编码的文本时,我必须解码。 (所以当读取->解码时)

当我编写时,我需要将其编码为 utf8。 (所以当写入->编码时)

但是我偶然发现了一个奇怪的场景。

我有一个停用词列表:

st = ['la', 'le', ...]

我需要过滤掉包含任何这些停用词的元组列表。

为了测试过滤方法,我执行了以下操作:

t = [(1, 'a'), (1, 'b'), (1, 'c')]  # list of tuples 
st = ['b']  # list of stopwords

# print all tuples which are not in st
print [tup for tup in t if any(i not in tup for i in st)]  

output:  [(1, 'a'), (1, 'c')]

这样就可以了。

现在,当我将其付诸实现时,我没有得到相同的结果。

停用词列表:

# -*- coding: utf-8 -*-
stop_words = {
        'fr':
            [
                'au', 'aux', 'avec', 'ce', 'ces',
                'le', 'la'
            ]

要过滤的元组:

 [(0.11363636363636366, u'arch'), (0.09090909090909093, u's'), (0.06818181818181819, u'la'), (0.04545454545454546, u'av'), (0.04545454545454546, u'champs'), (0.04545454545454546, u'de'), (0.04545454545454546, u'des'), (0.04545454545454546, u'grande'), (0.04545454545454546, u'ground'), (0.04545454545454546, u'm')]

过滤元组

[(0.11363636363636366, u'arch'), (0.09090909090909093, u's'), (0.06818181818181819, u'la'), (0.04545454545454546, u'av'), (0.04545454545454546, u'champs'), (0.04545454545454546, u'de'), (0.04545454545454546, u'des'), (0.04545454545454546, u'grande'), (0.04545454545454546, u'ground'), (0.04545454545454546, u'm')]

我还有:u'la'!

因此,为了测试 u'la' 是否在我的停用词列表中,我执行了以下操作:

[st for st in rs.stop_words['fr'] if st is 'la']
output: ['la']

但如果我这样做:

[st for st in rs.stop_words['fr'] if st is u'la']
output: []

该死!

我尝试了以下方法,但没有成功:

[st for st in rs.stop_words['fr'] if st is u'la'.encode('utf8')]
output: []

[st for st in rs.stop_words['fr'] if st is u'la'.decode('utf8')]
output: []

所以现在我陷入了未过滤元组的列表。

我做错了什么?

最佳答案

这个问题确实是一个转移注意力的问题。该问题与编码和解码无关;相反,问题是您正在比较两种不同的类型。一个字节字符串is永远不会等同于具有相同内容的 Unicode 字符串。

你可以做的(但见下文)是使用 ==相反:

>>> u'la' == 'la'
True

即使类型强制也无助于通过 is等价:

>>> u'la' is unicode('la')
False

...因为is比较的是身份,而不是内容。

>>> '{0} {1}'.format(id(u'la'), id(unicode('la')))
'4458408432 4458408480'

4458408432 不是 4458408480,所以 is事实并非如此。

(如果你这样做了 id(u'la') ,然后是 id(unicode('la')) ,你可能会误导性地获得相同的 id 两次,因为第一个被快速垃圾收集,然后它的 id 被重用。我在写这篇文章时发生过这种情况.将它们放在同一个语句中表明它们实际上是不同的。)

Unicode 字符串和字节字符串之间的差异以及编码和解码函数在 Ned Bachtelder 的 Pragmatic Unicode 中得到了很好的解释。推介会。基本建议是在阅读任何内容后立即对其进行解码,并仅在需要输出时对其进行编码,这是非常有用的建议。在整个代码中使用 Unicode 字符串(当然,除非您确实需要字节是字节,而不是字符),并且您不会遇到不愉快的意外。

# Note the u' prefix throughout!
st = [u'au', u'aux', u'avec', u'ce', u'ces', u'le', u'la']

当然,在Python 3中,u'前缀是多余的,因为 Unicode 字符串是默认的。但对于 Python 2 或需要在两个平台上工作的代码(或只需要清楚字符串类型),请始终使用 u'对于字符串。

关于python 何时编码、何时解码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34087227/

相关文章:

java - 使用 URL.openStream() 下载的 HTML 内容始终包含无效字符

java - 如何让 cxf-xjc-plugin 以 utf-8 格式生成源代码

python - Selenium - 在每一行代码之后等待

python - 拆分文件名,更新日期,将文件名重新组合在一起,python

python - 如何在 python 中打印列表理解的进度?

python - 如何使用 python 从 json 文件打印特定值?

python - Django 限制每分钟的请求数

python - 在 python 2.7 中将参数和 manager.dict 传递给多处理池

时间序列的Python聚合

php - CSV 文件中值的奇怪二进制字符串(在 Laravel 中导入包含丹麦语 æ、ø 和 å 字母)