【发布时间】:2017-04-10 21:15:26
【问题描述】:
我有一个 csv 文件(参见下面的 [1]),其中包含非 ascii 文本(例如,Antonio Melé 之类的名称。该文件包含带有 URL、摘录和 cmets 的书籍列表。
在 Python 3.5 中,我像这样打开并处理文件:
# -*- coding: utf-8 -*-
import codecs
import csv
import pdb
def select_book_matching_keyword(books, kw):
"""
Will select the csv rows for which any column has matching keyword in it
Snippet from csv file:
`Django By Example,Antonio Melé,Using class-based ...`
`Antonio Melé`
becomes
`b'Antonio Mel\xc3\xa9'`
"""
selected_books = []
for book in books:
kw_in_any_column = [column for column in book if kw in column.decode()]
# >> Without the `column.decode()` above I cannot
# run this list comprehension (that is if I
# write `if kw in column` instead of `if kw in column.decode()
if kw_in_any_column:
# print(book)
selected_books.append(book)
return selected_books
if __name__=='__main__':
f = codecs.open('safari-annotations-export-3.csv', 'r', 'utf-8')
reader = csv.reader(f)
books = []
for row in reader:
book_utf8 = [column.encode("utf-8") for column in row]
books.append(book_utf8)
print(book_utf8)
pdb.set_trace()
现在打印 csv 的行(参见上面的 print(book_utf8))会给我如下结果:
[b'Django By Example', b'Antonio Mel\xc3\xa9', b'Using class-based views', b'2017-03-08', b'https://www.safaribooksonline.com/library/view/django-by-example/9781784391911/', b'https://www.safaribooksonline.com/library/view/django-by-example/9781784391911/ch01s09.html', b'https://www.safaribooksonline.com/a/django-by-example/5869158/', b'Using class-based views', b'']
首先,我有一个字节前缀。为什么? (Python 3.x 默认将字符串视为 unicode,Python 2.7 默认将其视为字节。)
然后我有这个:b'Antonio Mel\xc3\xa9' 而不是 Antonio Melé。
我知道我还没有完全掌握 Python 中编码的概念。在这里阅读了很多关于 SO 的帖子,但我还是不太明白。
- 所以如果我的csv文件有特殊字符,我需要以
utf-8打开它吗?我做到了。 - 然后,如果我遍历 csv 阅读器,获取所有行并将它们附加到列表中(不对列进行编码),然后尝试打印它,我得到一个错误(参见下面的 [2])。为什么我不能打印该列表?
[2] 尝试打印 csv 文件的行列表而不对行的列进行编码会给我一个错误:
(snip)
['Learning jQuery Deferreds', 'Terry Jones...', '2. The jQuery Deferred API', '2017-04-06', 'https://www.safaribooksonline.com/library/view/learning-jquery-deferreds/9781449369385/', 'https://www.safaribooksonline.com/library/view/learning-jquery-deferreds/9781449369385/ch02.html', 'https://www.safaribooksonline.com/a/learning-jquery-deferreds/6635517/', 'More Terminology: Resolve, Reject and Progress', '']
*** UnicodeEncodeError: 'ascii' codec can't encode character '\u2019' in position 368: ordinal not in range(128)
【问题讨论】:
-
(1) 你在列表中得到字节,因为你
encode()每一列。不要那样做。 (2) 如果您不进行编码,则会收到 UnicodeEncodeError,因为可能是您的环境(区域设置等)设置为 ASCII,或者可能是因为您的终端无法处理 Unicode。尝试写入打开的文件而不是使用print()。