在Python中从csv读取原始行和字典

dap*_*hez 2 python csv

我的情况:我正在读取一个csv文件。我想访问每行生成的字段的字典以及未解析的原始行。

最终的目标是对字段进行一些处理,使用结果来确定我感兴趣的行,并将这些行仅写入输出文件。

一个简单的解决方案,涉及两次读取文件,如下所示:

def dict_and_row(filename):
    with open(filename) as f:
        tmp = [row for row in DictReader(f)]

    with open(filename) as f:
        next(f)    # skip header
        for i, line in enumerate(f):
            if len(line.strip()) > 0:
                yield line.strip(), tmp[i]
Run Code Online (Sandbox Code Playgroud)

还有更好的建议吗?

编辑:更详细地说明使用情况。我打算用dict中的一些数据对行进行索引,然后使用此索引查找我感兴趣的行。类似:

d = {}
for raw, parsed in dict_and_row(somefile):
      d[(parsed["SOMEFIELD"], parsed ["ANOTHERFIELD"])] = raw
Run Code Online (Sandbox Code Playgroud)

然后再

for pair in some_other_source_of_pairs:
      if pair in d:
            output.write(d[pair])
Run Code Online (Sandbox Code Playgroud)

dap*_*hez 5

我最后用一个对象包装了文件,该对象保存了最后读取的行,并将该对象交给DictReader。

class FileWrapper:
  def __init__(self, f):
    self.f = f
    self.last_line = None

  def __iter__(self):
    return self

  def __next__(self):
    self.last_line = next(self.f)
    return self.last_line
Run Code Online (Sandbox Code Playgroud)

然后可以这样使用:

  f = FileWrapper(file_object)
  for row in csv.DictReader(f):
      print(row)   # that's the dict
      print(f.last_line)   # that's the line
Run Code Online (Sandbox Code Playgroud)

或者我可以实现dict_and_row

 def dict_and_row(filename):
    with open(filename) as f:
         wrapper = FileWrapper(f)
         reader = DictReader(wrapper)
         for row in reader:
              yield row, wrapper.last_line 
Run Code Online (Sandbox Code Playgroud)

这也允许访问其他属性,例如读取的字符数。

不确定这是最佳解决方案,但确实具有保留对字符串的访问权限的优点,因为它们最初是从文件中读取的。