Python csv获取原始原始数据行

nfzehxib  于 12个月前  发布在  Python
关注(0)|答案(4)|浏览(122)

在python中,读取和解析csv文件并逐行处理是很容易的:

reader = csv.reader(open("my_csv_file.csv"))
for row in reader:
    # row is an array or dict 
    parsed_data = my_data_parser(row)

其中 my_data_parser 是我自己的一段逻辑,它接受输入数据,解析并执行逻辑。
如果我的解析器失败,我想记录csv文件的整个原始行,但似乎从csv阅读器我没有更多的访问它。
是否可以检索原始原始行数据?

csga3l58

csga3l581#

csv.reader()似乎没有公开它正在迭代的文件对象,但是,您可以使用读取器的line_num属性来实现您想要的功能。
举例来说:

import csv

file = open("my_csv_file.csv")

lines = file.readlines()

reader = csv.reader(lines)

for row in reader:
    # row is an array or dict
    try:
        parsed_data = my_data_parser(row)
    except MyDataParserError:
        print(f"ERROR in line number {reader.line_num}")
        print("Full line:")
        print(lines[reader.line_num])

file.close()

备选

如果你想避免总是将文件加载到内存中,你可以保留最初的阅读文件的方式,只在发生错误时才将整个文件读取到内存中:

import csv

reader = csv.reader(open("my_csv_file.csv"))
for row in reader:
    # row is an array or dict 
    try:
        parsed_data = my_data_parser(row)
    except MyDataParserError:
        # Only read the whole file into memory when an error occurred.
        file = open("my_csv_file.csv")
        lines = file.readlines()
        file.close()

        print(f"ERROR in line number {reader.line_num}")
        print("Full line:")
        print(lines[reader.line_num])
h79rfbju

h79rfbju2#

作为reader.line_num的替代

for index, row in enumerate(reader):
    print(i + 1, row)
zaqlnxep

zaqlnxep3#

您可以使用访问行行号

reader.line_num

但是似乎没有直接的方法来访问实际的行(说是doc)。这里是迭代方法,避免在任何步骤中将整个文件读取到内存中:

import csv 
class MyException(Exception):
    pass

def super_logic(line): # Some silly logic to get test code running
   if len(line) != 2 or line[1] != '1':
       raise MyException("Invalid value")
   print("Process: %s" % line)

class LastLineReader:
    
    def __init__(self, fn ):
        self.fid = open(fn)
    def __iter__(self):
        return self
    def __next__(self):
        line = self.fid.readline() # Read single line and cache it local object
        if len(line) == 0:
            raise StopIteration()
        self.current_line = line.strip()
        return line
           

reader_with_lines = LastLineReader( "my_csv_file.csv" )
reader = csv.reader( reader_with_lines )
for line in reader:
   try:
     super_logic(line)
   except MyException as e:
     print("Got exception: %s at line '%s'" % ( e, reader_with_lines.current_line ))

(编辑:删除了其他解决方案,因为它们在其他PPL帖子中也可见)

unguejic

unguejic4#

此解决方案不会将整个文件读入内存。
它在文件的每一个读取行调用csv reader。不确定性能:

import csv
f = open(filename, 'r')

# first line are the column names
column_names = next(csv.reader([next(f)]))
for line in f:
    cols = next(csv.reader([line]))
    row = dict(zip(column_names, cols))
  • 线是原始线
  • 行对应于DictReader的输出

相关问题