【问题标题】:KeyError raised while CSV file is correctly placed and keys exist in the CSV file正确放置 CSV 文件且 CSV 文件中存在密钥时引发 KeyError
【发布时间】:2015-09-30 16:40:55
【问题描述】:

我有这个 Python 代码:

import csv

csvfile = 'stations-nl-2014-01.csv'

try:
    f = open(csvfile, 'r')
    reader = csv.DictReader(f, delimiter=';')

    for row in reader:
        print(row['name'], '--', row['type'])
finally:
    f.close()

我可以使用常规的 csv.reader() 方法,但有人告诉我使用 csv.DictReader() 是最佳做法,因为您可以按名称选择列,这使代码更具可读性。但是,当我使用普通的 csv.reader() 方法时,没有显示错误。当我使用 DictReader 时,我收到以下错误:

print(row['name'], '--', row['type']) KeyError: 'name'

当我将代码更改为:

import csv

csvfile = 'stations-nl-2014-01.csv'

try:
    f = open(csvfile, 'r')
    reader = csv.reader(f, delimiter=';')

    for row in reader:
        print(row)
finally:
    f.close()

...一切正常。但是使用 csv.DictReader() 并按列名选择行会引发错误。有人知道怎么修这个东西吗?我已经仔细检查了 .csv 文件的路径和列名,一切都正确(没有 DictReader 也可以正常工作)。

【问题讨论】:

  • print row.keys() 有没有给你任何有用的东西?
  • 您能否从您的 CSV 中提供一些示例行?我最初的假设是你需要row['Name']
  • 当我执行 row.keys() 时得到这个:dict_keys(['code\tuic\tnaam\tmiddel_naam\tkorte_naam\trdt_url\ttype\tgeo_lat\tgeo_lng']) 我尝试了列名 tnaamttype,它们在 dict_keys 列表中,但它们也会产生相同的错误.

标签: python csv


【解决方案1】:

这是一个不好的问题,因为没有人知道 CSV 文件中的内容。

但是我遇到了同样的情况,在第一个键上我遇到了键错误。 事实证明,最初在 Excel 中创建的文件是用 UTF-8 编码保存的,并且有一个静默 '\ufeff' 前缀

我的解决方法是将每个 dict 转换为使用 ascii 编码的字符串

def convert_row( row ):
row_dict = {}
for key, value in row.items():
    keyAscii = key.encode('ascii', 'ignore' ).decode()
    valueAscii = value.encode('ascii','ignore').decode()
    row_dict[ keyAscii ] = valueAscii
return row_dict

这也可以通过 map / lambda 来完成,例如

def ascii_encode( str ):
    return str.encode( 'ascii', 'ignore' ).decode()

def convert_row( row ):
    return dict(map( lambda(key,value) :
        (ascii_encode(key),ascii_encode(value) ), row.items() ) )

或者类似的东西

我的回答中的主要问题是,如果文件是 utf-8,可能需要对字符串进行 ascii_encode。

【讨论】:

  • 这解决了我的问题,通过 excel 创建的 .csv 文件在第一列名称“{'\ufeffid':.”之前包含以下行......
【解决方案2】:

1) 我在网上搜索了文件“stations-nl-2014-01.csv”,发现它没有“名称”列。虽然存在列“类型”。

它有以下列: 代码 uic naam middel_naam korte_naam rdt_url type geo_lat geo_lng

您确定不应该查找 row['naam']?

2) 如果上述方法不起作用,您可以使用 row.keys() 获取“行”字典包含的键列表。这将为您提供 csv.DictReader 实际识别的键的列表。

【讨论】:

  • 感谢您的回答。我故意将荷兰语的“naam”更改为“name”,以便这里的人们更好地理解代码。当我执行 row.keys() 时得到这个:dict_keys(['code\tuic\tnaam\tmiddel_naam\tkorte_naam\trdt_url\ttype\tgeo_lat\tgeo_lng']) 我尝试了列名 tnaamttype,它们在 dict_keys 列表中,但它们也会产生相同的错误。
  • 我遇到了同样的问题。我打印钥匙,它就在那里。我打印字典,它就在那里。我已经重命名了它,它仍然会发生。我已将整个字典复制到一个新字典中,但它仍然会发生。无论我如何称呼第一列,它都会给我一个 KeyError。它读取其他项目也没有问题,只是其名称的第一列。
  • @CashCow 也许用您的代码和相应的 CSV 文件创建一个关于此的新主题是个好主意?那时人们可能会更好地帮助你。
  • 我发现了问题。我只是认为你的问题不是很好,因为它似乎相当本地化为一个名为“stations-nl-2014-01.csv”的文件,这对任何有问题的人来说都没有任何意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
  • 1970-01-01
  • 2020-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多