【问题标题】:Trouble reading in Unicode strings from CSV file to DictReader in Python在 Python 中将 Unicode 字符串从 CSV 文件读取到 DictReader 时遇到问题
【发布时间】:2015-08-31 11:27:51
【问题描述】:

我正在尝试使用 DictReader 读取一个 CSV 文件。

但是这样做:

with("BeerRatings.csv", "r", "utf-8") as f:
    reader = csv.DictReader(f)
    for line in reader:
        print line

给了我一些丑陋的 unicode:

{'Rating': '4', 'Brewery': 'Tr\xc3\xb6egs Brewing Company', 'Beer name': 'Tr\xc3\xb6egs Hopback Amber Ale'}
{'Rating': '4.59', 'Brewery': 'Brasserie Dieu Du Ciel', 'Beer name': 'P\xc3\xa9ch\xc3\xa9 Mortel - Bourbon Barrel Aged'} etc.

因此,在阅读 stackoverflow 时,我使用编解码器模块将我的代码编辑为:

import codecs

with codecs.open("BeerRatings.csv", "r", "utf-8") as f:
    reader = csv.DictReader(f)
    for line in reader:
        print line

但这给了我一个UnicodeEncodeError: 'ascii' codec can't encode character u'\xea' in position 9: ordinal not in range(128)

关于如何解决此问题的任何提示?

更新,也就是更多的到处乱窜:

def UnicodeDictReader(utf8_data, **kwargs):
    csv_reader = csv.DictReader(utf8_data, **kwargs)
    for row in csv_reader:
        yield {key: unicode(value, 'utf-8') for key, value in row.iteritems()}

with open("BeerRatings.csv", "r") as f:
    reader = UnicodeDictReader(f)
    for line in reader:
        print line

这仍然给我一个不太理想的输出......

{'Rating': u'4', 'Brewery': u'Tr\xf6egs Brewing Company', 'Beer name': u'Tr\xf6egs Hopback Amber Ale'}
{'Rating': u'4.59', 'Brewery': u'Brasserie Dieu Du Ciel', 'Beer name': u'P\xe9ch\xe9 Mortel - Bourbon Barrel Aged'}

【问题讨论】:

  • 你用的是什么 Python 版本?
  • 尝试使用this page上的Unicode Writer和Reader的最后一个示例
  • @VikasNehaOjha - 尝试进行适当的更改(查看我的帖子更新)但无济于事......有什么建议吗?
  • 嗯,我认为这是意料之中的,请检查控制台的编码。
  • @VikasNehaOjha - 你是什么意思?

标签: python-2.7 csv dictionary unicode codec


【解决方案1】:

Python 2.X 中的csv 模块要求输入文件以二进制形式打开,并且不支持编码。但是,它与 UTF-8 兼容,但您必须自己解码为 Unicode:

import csv

with open('BeerRatings.csv','rb') as f:
    reader = csv.DictReader(f)
    for line in reader:
        for k,v in line.iteritems():
            print k.decode('utf8'),':',v.decode('utf8')
        print

输出:

Rating : 4
Brewery : Tröegs Brewing Company
Beer name : Tröegs Hopback Amber Ale

Rating : 4.59
Brewery : Brasserie Dieu Du Ciel
Beer name : Péché Mortel - Bourbon Barrel Aged

编辑

根据您的UnicodeDictReader,您仍然需要像我一样打印键/值对,否则您将获得dict 的默认打印,它通过字符串的repr() 显示转义数据。也以二进制模式打开。这对某些操作系统很重要,尤其是 Windows。

import csv

def UnicodeDictReader(utf8_data, **kwargs):
    csv_reader = csv.DictReader(utf8_data, **kwargs)
    for row in csv_reader:
        yield {key.decode('utf8'):value.decode('utf8') for key, value in row.iteritems()}

def prettydict(D):
    return u'{' + u', '.join(u"'{}': '{}'".format(k,v) for k,v in D.iteritems()) + u'}'

with open("BeerRatings.csv", "rb") as f:
    reader = UnicodeDictReader(f)
    for line in reader:
        print prettydict(line)

输出:

{'Rating': '4', 'Brewery': 'Tröegs Brewing Company', 'Beer name': 'Tröegs Hopback Amber Ale'}
{'Rating': '4.59', 'Brewery': 'Brasserie Dieu Du Ciel', 'Beer name': 'Péché Mortel - Bourbon Barrel Aged'}

【讨论】:

  • 我认为您的代码底部不完整 - 您想打印其他内容吗?而且,我试图保留单行输入格式 - 最好的方法是什么?
  • 不,这只是字典之间的空白行。
  • 马克-感谢您提供的好信息。我们可以更改代码以使输出的格式与原始格式相同吗? (全部在一行中)
  • 用你编辑的`UnicodeDictReader`函数,为什么with open("BeerRatings.csv", "rb") as f: reader = UnicodeDictReader(f) for line in reader: print line没有给我们想要的输出?
  • @SpicyClubSauce,Python 对象有两种显示方式:通过str() 的“漂亮”方式和通过repr() 的调试方式。 repr() 转义非 ASCII 字节,因此您可以准确地看到字符串中的内容。这是listdict 项目使用的默认值。如果您不想要默认值,则必须滚动自己的显示。我会用一个例子来更新答案。
猜你喜欢
  • 2014-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-19
  • 1970-01-01
  • 1970-01-01
  • 2019-02-21
  • 1970-01-01
相关资源
最近更新 更多