如何从文件中获取原始CSV行
比如我有一个这样的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
对象。
我最初的示例尝试使用csvdata.tell()
,但你不能这样做,因为当某个东西调用next()
时,Python显然会丢失文件指针的位置,而csv.reader
内部似乎会这样做。幸运的是,它还提供了line_num
,这对于这段代码来说已经足够了。