【问题标题】:Python: Extra comma on csv.Dictreader columnPython:csv.Dictreader 列上的额外逗号
【发布时间】:2019-08-04 20:41:42
【问题描述】:

我有这个读取函数,它使用 csv.DictReader 读取 csv 文件。 file.csv 用逗号分隔,它完全读取。但是,我文件的这一部分有一列包含多个逗号。我的问题是,如何确保逗号被计为列的一部分?我无法更改我的 csv 文件以满足标准。

文本文件

ID,Name,University,Street,ZipCode,Country
12,Jon Snow,U of Winterfell,Winterfell #45,60434,Westeros
13,Steve Rogers,NYU,108, Chelsea St.,23333,United States
20,Peter Parker,Yale,34, Tribeca,32444,United States
34,Tyrion Lannister,U of Casterly Rock,Kings Landing #89, 43543,Westeros

所需的输出是这样的:

{'ID': '12', 'Name': 'Jon Snow', 'University': 'U of Winterfell', 'Street': 'Winterfell #45', 'ZipCode': '60434', 'Country': 'Westeros'}
{'ID': '13', 'Name': 'Steve Rogers', 'University': 'NYU', 'Street': '108, Chelsea St.', 'ZipCode': '23333', 'Country': 'United States'}
{'ID': '20', 'Name': 'Peter Parker', 'University': 'Yale', 'Street': '34, Tribeca', 'ZipCode': '32444', 'Country': 'United States'}
{'ID': '34', 'Name': 'Tyrion Lannister', 'University': 'U of Casterly Rock', 'Street': 'Kings Landing #89', 'ZipCode': '43543', 'Country': 'Westeros'}

正如你所知道的,由于数字,“街道”至少有两个逗号:

13,Steve Rogers,NYU,108, Chelsea St.,23333,美国

20,彼得帕克,耶鲁,34,翠贝卡,32444,美国

注意:大多数被读取的列都由 str,str 分割,但在“Street”列下,它后面跟着一个 str,str(逗号后有一个额外的空格)。我希望这是有道理的。

我尝试查看的选项是使用 re.split,但我不知道如何在我的读取文件上实现它。我在想re.split(r'(?!\s),(?!\s)',x[:-1])?如何确保我的文件中的格式将计入任何列?我不能使用熊猫。

我当前的输出现在看起来像这样:

{'ID': '12', 'Name': 'Jon Snow', 'University': 'U of Winterfell', 'Street': 'Winterfell #45', 'ZipCode': '60434', 'Country': 'Westeros'}
{'ID': '13', 'Name': 'Steve Rogers', 'University': 'NYU', 'Street': '108', 'ZipCode': 'Chelsea St.', 'Country': '23333', None: ['United States']}
{'ID': '20', 'Name': 'Peter Parker', 'University': 'Yale', 'Street': '34', 'ZipCode': 'Tribeca', 'Country': '32444', None: ['United States']}
{'ID': '34', 'Name': 'Tyrion Lannister', 'University': 'U of Casterly Rock', 'Street': 'Kings Landing #89', 'ZipCode': '43543', 'Country': 'Westeros'}

这是我的阅读功能:

import csv

list = []
with open('file.csv', mode='r') as csv_file:
  csv_reader = csv.DictReader(csv_file, delimiter=",", skipinitialspace=True)

  for col in csv_reader:
    list.append(dict(col))
    print(dict(col))

【问题讨论】:

  • 使用任何 CSV 库都无法解决此问题。它应该如何知道哪些逗号是分隔符,哪些是字段值的一部分?
  • 如果字段包含逗号,则必须将其放在引号中。
  • @Barmar 有没有办法用 csv.reader 做到这一点?还是有什么不同?
  • @Barmar 我可以在阅读功能上实现我的 re.split 示例吗?
  • 如果一个真正的字段永远不会以空格开头,我猜是这样。当你尝试时发生了什么?

标签: python python-3.x file csv reader


【解决方案1】:

如果文件不是有效的 CSV 格式,则不能使用 csv

您需要在普通线路上调用re.split(),而不是在字典上。

list = []
with open('file.csv', mode='r') as csv_file:
    keys = csv_file.readline().strip().split(',') # Read header line
    for line in csv_file:
        line = line.strip()
        row = re.split(r'(?!\s),(?!\s)',line)
        list.append(dict(zip(keys, row)))

【讨论】:

    【解决方案2】:

    该问题的实际解决方案是修改生成 csv 文件的脚本。

    如果您有机会修改该输出,您可以做两件事

    • 使用逗号以外的分隔符,例如| 符号或;,无论您认为它在字符串中不存在。
    • 或者用" 将所有列括起来,这样你就可以用, 来分割它们,, 是实际的分隔符。

    如果您没有机会修改输出。

    如果您确定多个逗号仅在街道列中;那么您应该使用csv.reader 而不是DictReader 这样您就可以通过您已经确定的索引获取列。例如row[0] 将是ID row[1] 将是Namerow[-1] 将是Country row[-2] 将是ZipCode 所以我猜row[2:-2] 会给你你需要的东西。可以安排索引,但我想这个想法很清楚。

    希望对您有所帮助。


    编辑:

    import csv
    
    list = []
    with open('file.csv', mode='r') as csv_file:
      csv_reader = csv.reader(csv_file, delimiter=",", skipinitialspace=True)
      # pass the header row
      next(csv_reader)
      for row in csv_reader:
      list.append({"ID": row[0],
                   "Name": row[1],
                   "University": row[2],
                   "Street": ' '.join(row[3:-2]),
                   "Zipcode": row[-2],
                   "Country": row[-1]})
    print(list)
    

    -- 这是输出(带有 pprint)

    [{'Country': 'Westeros',
    'ID': '12',
    'Name': 'Jon Snow',
    'Street': 'Winterfell #45',
    'University': 'U of Winterfell',
    'Zipcode': '60434'},
    {'Country': 'United States',
    'ID': '13',
    'Name': 'Steve Rogers',
    'Street': '108 Chelsea St.',
    'University': 'NYU',
    'Zipcode': '23333'},
     {'Country': 'United States',
    'ID': '20',
    'Name': 'Peter Parker',
    'Street': '34 Tribeca',
    'University': 'Yale',
    'Zipcode': '32444'},
     {'Country': 'Westeros',
    'ID': '34',
    'Name': 'Tyrion Lannister',
    'Street': 'Kings Landing #89',
    'University': 'U of Casterly Rock',
    'Zipcode': '43543'}]
    

    -- 第二次编辑 在街上编辑了索引。 问候。

    【讨论】:

    • 他明确表示不能更改文件格式。
    • 这就引出了我回答的第二部分:)
    • @rkirmizi 那么我的读取功能在将其更改为 csv.reader 并保持字典格式后会是什么样子?因为如果我要更改它,Dictreader to reader on my code 它会给我一个错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-13
    • 2016-09-07
    • 2015-12-21
    • 2018-07-17
    • 1970-01-01
    • 2020-09-12
    • 2021-10-31
    相关资源
    最近更新 更多