我有一个包含大量.csv
文件的目录,我正在尝试编写一个在目录中的所有文件上运行的脚本,同时执行以下操作:
从所有csv文件中删除第一行和最后一行
我正在运行以下代码:
import glob
list_of_files = glob.glob('path/to/directory/*.csv')
for file_name in list_of_files:
fi = open(file_name, 'r')
fo = open(file_name.replace('csv', 'out'), 'w') #make new output file for each file
num_of_lines = file_name.read().count('\n')
file_name.seek(0)
i = 0
for line in fi:
if i != 1 and i != num_of_lines-1:
fo.write(line)
fi.close()
fo.close()
我使用python3 script.py
运行脚本。虽然我没有收到任何错误,但我也没有得到任何输出文件。
答案 0 :(得分:2)
您的代码中存在多个问题。首先,您计算文件名而不是文件对象的行数。第二个问题是你初始化i=0
并与之进行比较,但它永远不会改变。
就个人而言,我只是将文件转换为"行"的列表,切断第一个和最后一个并将所有文件写入新文件:
import glob
list_of_files = glob.glob('path/to/directory/*.csv')
for file_name in list_of_files:
with open(file_name, 'r') as fi:
with open(file_name.replace('csv', 'out'), 'w') as fo:
for line in list(fi)[1:-1]: # for all lines except the first and last
fo.write(line)
使用with open
允许省略close
次调用(因为它们是隐式完成的),即使发生异常也是如此。
如果仍未提供输出,您可以使用print
语句显示正在处理的文件:
print(file_name) # just inside the for-loop before any `open` calls.
由于您使用的是python-3.5,因此您也可以使用pathlib
:
import pathlib
path = pathlib.Path('path/to/directory/')
# make sure it's a valid directory
assert path.is_dir(), "{} is not a valid directory".format(p.absolute())
for file_name in path.glob('*.csv'):
with file_name.open('r') as fi:
with pathlib.Path(str(file_name).replace('.csv', '.out')).open('w') as fo:
for line in list(fi)[1:-1]: # for all lines except the first and last
fo.write(line)
正如Jon Clements所指出的,有一种比[1:-1]
更好的方法是使用生成器函数排除第一行和最后一行。这样你肯定会减少使用的内存量,也可能会提高整体性能。例如,您可以使用:
import pathlib
def ignore_first_and_last(it):
it = iter(it)
firstline = next(it)
lastline = next(it)
for nxtline in it:
yield lastline
lastline = nxtline
path = pathlib.Path('path/to/directory/')
# make sure it's a valid directory
assert path.is_dir(), "{} is not a valid directory".format(p.absolute())
for file_name in path.glob('*.csv'):
with file_name.open('r') as fi:
with pathlib.Path(str(file_name).replace('.csv', '.out')).open('w') as fo:
for line in ignore_first_and_last(fi): # for all lines except the first and last
fo.write(line)