更改第1列中的数字

时间:2011-01-08 23:24:52

标签: python file

我知道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()

5 个答案:

答案 0 :(得分:1)

根本不要执行readlines(),而是:

for line in ifile: 

另外,避免使用名称list命名变量。由于list()是一个内置函数,因此您正在隐藏该名称,这是不好的做法。

没有必要deldel 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需要退出,或者文件的其余部分仍然会运行。