尝试在 Python 中将字典列表写入 csv,遇到编码问题



所以我遇到了一个编码问题,这个问题源于用Python编写字典到csv。

下面是一个示例代码:

import csv
some_list = ['jalapexc3xb1o']
with open('test_encode_output.csv', 'wb') as csvfile:
    output_file = csv.writer(csvfile)
    for item in some_list:
        output_file.writerow([item])

这工作得很好,给了我一个写有"墨西哥辣椒"的 csv 文件。

但是,当我创建一个包含此类 UTF-8 字符的值的字典列表时......

import csv
some_list = [{'main': ['4 dried ancho chile peppers, stems, veins
            and seeds removed']}, {'main': ['2 jalapexc3xb1o 
            peppers, seeded and chopped', '1 dash salt']}]
with open('test_encode_output.csv', 'wb') as csvfile:
    output_file = csv.writer(csvfile)
    for item in some_list:
        output_file.writerow([item])

我只得到一个包含 2 行的 csv 文件,其中包含以下条目:

{'main': ['4 dried ancho chile peppers, stems, veins and seeds removed']}
{'main': ['2 jalapexc3xb1o peppers, seeded and chopped', '1 dash salt']}

我知道我的东西是用正确的编码写的,但是因为它们不是字符串,所以当它们被csv.writer写出来时,它们是按原样编写的。这是令人沮丧的。我在这里搜索了一些类似的问题,人们提到使用 csv。DictWriter,但这对我来说效果不佳,因为我的词典列表不仅仅是 1 个键'main'。有些还有其他键,如'toppings''crust'等。不仅如此,我还在对它们做更多的工作,最终的输出是将成分格式化为数量、单位、成分,所以我最终会得到一个词典列表,比如

[{'main': {'amount': ['4'], 'unit': [''], 
'ingredient': ['dried ancho chile peppers']}},
{'topping': {'amount': ['1'], 'unit': ['pump'], 
'ingredient': ['cool whip']}, 'filling': 
{'amount': ['2'], 'unit': ['cups'], 
'ingredient': ['strawberry jam']}}]

说真的,任何帮助将不胜感激,否则我将不得不在 LibreOffice 中使用查找和替换来修复所有这些 \x** UTF-8 编码。

谢谢!

您正在将字典写入 CSV 文件,而.writerow()期望具有单数值的列表在写入时转换为字符串。

不要写字典,正如你所发现的,这些词典会变成字符串表示形式。

您需要确定如何将每个字典的键和/或值转换为列,其中每个列都是单个基元值。

例如,如果您只想写入main密钥(如果存在),则这样做:

with open('test_encode_output.csv', 'wb') as csvfile:
    output_file = csv.writer(csvfile)
    for item in some_list:
        if 'main' in item:
            output_file.writerow(item['main'])

其中假定与'main'键关联的值始终是值列表。

如果要保留具有 Unicode 值的字典,那么您使用了错误的工具。CSV 是一种平面数据格式,只有行和基元列。改用可以保留适量信息的工具。

对于具有字符串键、列表、数字和 unicode 文本的字典,可以使用 JSON,如果涉及更复杂的自定义数据类型,则可以使用 pickle。使用 JSON 时,您确实希望从字节字符串解码为 Python Unicode 值,或者始终使用 UTF-8 编码的字节字符串,或者使用 encoding 关键字说明json库应如何处理字符串编码:

import json
with open('data.json', 'w') as jsonfile:
    json.dump(some_list, jsonfile, encoding='utf8')

因为 JSON 字符串始终是 unicode 值。encoding的默认值是utf8,但为了清楚起见,我在这里添加了它。

再次加载数据:

with open('data.json', 'r') as jsonfile:
    some_list = json.load(jsonfile)

请注意,这将返回 unicode 字符串,而不是编码为 UTF8 的字符串。

pickle模块的工作方式大致相同,但数据格式不是人类可读的:

import pickle
# store
with open('data.pickle', 'wb') as pfile:
    pickle.dump(some_list, pfile)
# load
with open('data.pickle', 'rb') as pfile:
    some_list = pickle.load(pfile)

pickle将完全按照您存储的数据返回您的数据。字节字符串仍然是字节字符串,unicode 值将恢复为 unicode。

正如你在输出中看到的,你已经使用了一个字典,所以如果你想处理这个字符串,你必须写这个:

import csv
some_list = [{'main': ['4 dried ancho chile peppers, stems, veins', 'xc2xa0xc2xa0xc2xa0 and seeds removed']}, {'main': ['2 jalapexc3xb1o peppers, seeded and chopped', '1 dash salt']}]
with open('test_encode_output.csv', 'wb') as csvfile:
    output_file = csv.writer(csvfile)
    for item in some_list:
        output_file.writerow(item['main'])  #so instead of [item], we use item['main']

我知道这可能不是您想要的代码,因为它限制您调用每个键 main,但至少它现在得到了处理。

你可能想更好地制定你想做的事情,因为现在还不清楚(至少对我来说)。例如,您是否想要一个 csv 文件,该文件在第一个单元格中为您提供 main,然后 4 个干燥......

最新更新