如何从文件中获取原始CSV行

1 投票
2 回答
69 浏览
提问于 2025-04-14 16:12

比如我有一个这样的CSV文件:

a,b,c
a1,b1,c1

我想要获取解析后的数据和原始的CSV行。举个例子:

import csv
with open('some.csv') as f:
reader = csv.reader(f)
for row in reader:
    # getting original raw csv line
    print(row)
    print(origin_row)
    # should print something like this:
    # ["a", "b", "c"]
    # a,b,c 
     

CSV数据可能包含任何类型的数据。我需要这样做是为了存储解析后的行和原始行,以便进行验证、确认等。我需要每一行或每个实体都有解析的数据和原始数据。

2 个回答

0

一个可能的解决办法是使用 itertools.tee

不过,如果值里面有换行符的话,这个方法就不适用了——也就是说,一个CSV文件中的一行数据可能会分成多行。

import csv
from itertools import tee

with open("data.csv", "r") as f:
    f1, f2 = tee(f)
    for row, original_row in zip(csv.reader(f1), f2):
        # getting origin raw csv line
        print(row, original_row)

输出结果:

['a', 'b', 'c'] a,b,c

['a1', 'b1', 'c1'] a1,b1,c1

2

你的问题其实不太明确,因为在你真正解析数据之前,你无法知道多少行原始数据对应于一行CSV。因为CSV中的一行可能会包含换行符,所以你似乎假设它可以被表示为一行。

这里有一个复杂的示例,它使用两个打开的文件句柄来分别读取解析后的原始数据。

import csv

def rawcsv(filename):
    with open(filename, "r") as csvdata, open(
            filename, "rb") as rawdata:
        reader = csv.reader(csvdata)
        prev = 0
        for row in reader:
            # Where is the file pointer now?
            pos = reader.line_num
            # Read the same amount of rawdata
            raw = b"".join([rawdata.readline() for _ in range(pos - prev)])
            prev = pos
            yield raw, row

for raw, row in rawcsv("some.csv"):
    print(f"Raw: {raw}")
    print(f"Row: {row}")

(你需要把这个放在一个函数里,这样yield才有意义。)

注意,raw会是一个bytes对象。

示例:https://ideone.com/iqBQf0

我最初的示例尝试使用csvdata.tell(),但你不能这样做,因为当某个东西调用next()时,Python显然会丢失文件指针的位置,而csv.reader内部似乎会这样做。幸运的是,它还提供了line_num,这对于这段代码来说已经足够了。

撰写回答