显然某些csv输出实现会在最后一行的右边截断字段分隔符,而在字段为空时只截断文件中的最后一行。
示例输入csv,字段'c'和'd'可以为空:
a|b|c|d
1|2||
1|2|3|4
3|4||
2|3
在下面的脚本中,我怎么知道我是否在最后一行,所以我知道如何妥善处理它?</ p>
import csv
reader = csv.reader(open('somefile.csv'), delimiter='|', quotechar=None)
header = reader.next()
for line_num, row in enumerate(reader):
assert len(row) == len(header)
....
答案 0 :(得分:13)
基本上你只知道在用完之后你已经用完了。所以你可以包装reader
迭代器,例如如下:
def isLast(itr):
old = itr.next()
for new in itr:
yield False, old
old = new
yield True, old
并将您的代码更改为:
for line_num, (is_last, row) in enumerate(isLast(reader)):
if not is_last: assert len(row) == len(header)
等
答案 1 :(得分:2)
如果您期望每行中有固定数量的列,那么您应该防范:
(1)任何行更短 - 例如编写器(SQL Server /查询分析器IIRC)可以随机忽略尾随的 ;用户可以使用文本编辑器来处理文件,包括留空行。
(2)任何行更长 - 例如逗号没有正确引用。
你不需要任何花哨的技巧。在你的行读取循环中只是一个老式的if-test:
for row in csv.reader(...):
ncols = len(row)
if ncols != expected_cols:
appropriate_action()
答案 2 :(得分:2)
我知道这是一个老问题,但我想出的答案与提出的答案不同。在迭代它时,reader
对象已经递增了line_num
属性。然后我首先使用row_count
获取总行数,然后将其与line_num
进行比较。
import csv
def row_count(filename):
with open(filename) as in_file:
return sum(1 for _ in in_file)
in_filename = 'somefile.csv'
reader = csv.reader(open(in_filename), delimiter='|')
last_line_number = row_count(in_filename)
for row in reader:
if last_line_number == reader.line_num:
print "It is the last line: %s" % row
答案 3 :(得分:1)
如果您想要获得最后一行,请尝试以下代码:
with open("\\".join([myPath,files]), 'r') as f:
print f.readlines()[-1] #or your own manipulations
如果要继续使用行中的值,请执行以下操作:
f.readlines()[-1].split(",")[0] #this would let you get columns by their index
答案 4 :(得分:0)
只需将行延伸到标题的长度:
for line_num, row in enumerate(reader):
while len(row) < len(header):
row.append('')
...
答案 5 :(得分:0)
当csv阅读器读取
中的最后一行时,你能不能捕获错误尝试: ......在这里做你的东西...... 除了:StopIteration
条件?
有关如何使用try:catch:Python CSV DictReader/Writer issues
的示例,请参阅stackoverflow上的以下python代码答案 6 :(得分:0)
如果您使用for row in reader:
,则只会在读完最后一项后停止循环。