【问题标题】:Python Parse CSV CorrectlyPython 正确解析 CSV
【发布时间】:2012-08-31 01:36:31
【问题描述】:

我对 Python 很陌生。我想解析一个 csv 文件,以便它能够识别引用的值 - 例如

1997,福特,E350,“超级豪华卡车”

应该拆分为

('1997', 'Ford', 'E350', '超级豪华卡车')

不是

('1997', 'Ford', 'E350', '"Super', '豪华卡车"')

如果我使用str.split(,) 之类的东西,以上是我得到的。

我该怎么做? 最好将这些值存储在数组或其他数据结构中吗?因为在我从 csv 中获取这些值之后,我希望能够轻松选择,假设任意两列并将其存储为另一个数组或其他一些数据结构。

【问题讨论】:

  • 我已经编辑了这个问题。如果我只使用分隔符 ',' 它无法识别引号内的 ','
  • 你必须定义'quote'

标签: python parsing csv


【解决方案1】:

您应该使用csv 模块:

import csv
reader = csv.reader(['1997,Ford,E350,"Super, luxurious truck"'], skipinitialspace=True)
for r in reader:
    print r

输出:

['1997', 'Ford', 'E350', 'Super, luxurious truck']

【讨论】:

  • 谢谢。但是当我尝试从文件中读取时,我收到以下错误-csv.Error: line contains NULL byte 我的文件可能包含一百万行,如下所示-1,,"Warn, unknown error","car-8554.gif","car.gif","crs_04","change rand str, cut pos, 35289, add size, 9242"
  • @cornerstone:你是如何创建这个文件的?您不会通过正常方式在此处显示 NULL 字节,但如果它在文件中,如果您将其视为文本,则通过几乎任何方式读取它都会成为问题。
  • @Wooble 它是通过将 SQL 数据值转储到 csv 文件来创建的。我认为空值是由于连续的“,”出现在行中。我已经找到了解决方案。 with open(r'car.csv') as csv_file: ... reader = csv.reader((line.replace('\0','') for line in csv_file), delimiter=',', quotechar='"') ... print(reader.next())
【解决方案2】:

您必须在csv.reader() 语句中将双引号定义为quotechar

>>> with open(r'<path_to_csv_test_file>') as csv_file:
...     reader = csv.reader(csv_file, delimiter=',', quotechar='"')
...     print(reader.next())
... 
['1997', 'Ford', 'E350', 'Super, luxurious truck']
>>> 

【讨论】:

    【解决方案3】:

    以下方法效果很好

    d = {}
    d['column1name'] = []
    d['column2name'] = []
    d['column3name'] = []
    
    dictReader = csv.DictReader(open('filename.csv', 'rb'), fieldnames = ['column1name', 'column2name', 'column3name'], delimiter = ',', quotechar = '"')
    
    for row in dictReader:
        for key in row:
            d[key].append(row[key])
    

    列以列名作为键存储在字典中。

    【讨论】:

    • col3name 前面缺少一个开始单引号。
    • 打开的文件句柄会发生什么?
    【解决方案4】:

    如果您不想使用 CSV 模块,则需要使用正则表达式。试试这个:

    import re
    regex = ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)"
    string = '1997,Ford,E350,"Super, luxurious truck"'
    array = re.split(regex, string)
    
    print(array[3])
    "Super, luxurious truck"
    

    【讨论】:

      【解决方案5】:

      csv.py 模块可能没问题 - 但如果您想查看和/或控制它的工作方式,这里有一个基于协程的小型仅 python 解决方案:

      def csv_parser(delimiter=','):
          field = []
          while True:
              char = (yield(''.join(field)))
              field = []
      
              leading_whitespace = []    
              while char and char == ' ':
                  leading_whitespace.append(char)
                  char = (yield)
      
              if char == '"' or char == "'":
                  suround = char
                  char = (yield)
                  while True:
                      if char == suround:
                          char = (yield)
                          if not char == suround:
                              break
      
                      field.append(char)
                      char = (yield)
      
                  while not char == delimiter:
                      if char == None:
                          (yield(''.join(field)))
                      char = (yield)
              else:
                  field = leading_whitespace
                  while not char == delimiter:
                      if char == None:
                          (yield(''.join(field)))
                      field.append(char)
                      char = (yield)
      
      def parse_csv(csv_text):
          processor = csv_parser()
          processor.next() # start the processor coroutine
      
          split_result = []
          for c in list(csv_text) + [None]:
              emit = processor.send(c)
              if emit:
                  split_result.append(emit)
      
          return split_result
      
      print parse_csv('1997,Ford,E350,"Super, luxurious truck"')
      

      在 python 2.7 上测试

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-11-25
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 2017-07-19
        • 2016-03-12
        • 2018-05-30
        • 1970-01-01
        相关资源
        最近更新 更多