我知道sed或awk可能会更优雅地解决这类问题。但是我采用了python方式,所以问题是我想将数据文件的第一列重新编号为1到文件中的#of行。通过readlines读取文件是个好主意吗?对于小文件,但我认为不是大文件。所以这是我作为第一次尝试而提出的,任何意见都表示赞赏。
#!/usr/bin/env python
import sys
try:
infilename = sys.argv[1]; outfilename = sys.argv[2];
except:
print "Usage is <script> inFile outFile"
ifile = open(infilename,'r')
ofile = open(outfilename, 'w')
lines = ifile.readlines();
i=1
for line in lines:
list = line.split();
list[0] = i
i += 1
for val in list:
ofile.write("%d " % int(val))
ofile.write('\n')
del list
ifile.close()
ofile.close()
答案 0 :(得分:1)
根本不要执行readlines()
,而是:
for line in ifile:
另外,避免使用名称list
命名变量。由于list()
是一个内置函数,因此您正在隐藏该名称,这是不好的做法。
没有必要del
像del list
这样的本地变量;这是Python的垃圾收集器自动处理的。 (在CPython中,垃圾收集器是引用计数和确定性的。)
答案 1 :(得分:1)
with open(infilename,'r') as ifile:
with open(outfilename, 'w') as ofile:
for (nr, line) in enumerate(ifile):
line = line.split()
line[0] = nr
line.append('\n')
ofile.write(' '.join(line))
答案 2 :(得分:1)
您可以遍历文件以仅保留内存中的当前行:
#!/usr/bin/env python
import sys
try:
# dont use ; !
infilename = sys.argv[1]
outfilename = sys.argv[2]
except:
print "Usage is <script> inFile outFile"
# you could use `with` here if you have a Python 2.7
ifile = open(infilename,'r')
ofile = open(outfilename, 'w')
# no need to count yourself, enumerate does that
# plus when you iterate over a file you get lines too
for i, line in enumerate(ifile, start=1):
# dont shadow builtins like `list`
parts = line.split()
parts[0] = i
# join is the inverse function to split
new_line = ' '.join("%d" % int(val) for val in parts)
ofile.write(new_line + '\n')
ifile.close()
ofile.close()
@Umut Tabak:("%d" % int(val) for val in parts)
是generator expression,它们有点像懒惰列表。它提供了与列表推导["%d" % int(val) for val in parts]
相同的项目,但没有实际创建列表。
顺便说一句,for block可以编写得更短,但它稍有不同,因为它不会强制所有行都是int
s:
for i, line in enumerate(ifile, start=1):
parts = line.split()
parts[0] = "%d" % i
new_line = ' '.join(parts)
ofile.write(new_line + '\n')
答案 3 :(得分:1)
#!/usr/bin/env python
import sys
try:
ifile = open(sys.argv[1], 'r')
ofile = open(sys.argv[2], 'w+')
except:
print "Usage is <script> inFile outFile"
else:
for i, line in enumerate(ifile, start=1):
items = [str(i)] + line.split()[1:]
ofile.write(' '.join(items) + '\n')
ifile.close()
ofile.close()
我想回答一些问题。第一个是try块,我正在检查我是否可以打开文件。如果没有输入文件名,或者任何一个文件不可打开,您将收到使用消息。你当然可以解决这个问题:检查文本,并返回适当的返回用法,并尝试打开文件,并适当地返回文件打开失败。或者,您可以检查特定的异常并返回不同的消息。
接下来,枚举是让解释器跟踪索引的便捷方法。在循环本身,我加入了枚举索引和读取行的“切片”(除了第一项之外的所有内容)。然后我加入一个空格并用换行符写下来。
这很简洁。
答案 4 :(得分:0)
您不需要拆分整行,只需拆分第一列:
for i,line in enumerate(ifile,1):
first,remaining = line.split(' ',1)
ofile.write("{0} {1}".format(i,remaining))
此外,您的except
需要退出,或者文件的其余部分仍然会运行。