我有一个用这样的列写的文件(我写第一行但是更长):
Ncol 10 Nrow 9276
NO_POL = 2
NO_IF = 8
NO. ANTENNA SUBARRAY TSYS TANT
1 1 1 37 35
2 37 35
3 37 35
4 1 1 37 35
5 37 35
6 37 35
7 3 1 37 35
8 37 35
9 37 35
10 3 1 37 35
11 37 35
我想在另一个文件中复制该文件中出现的天线数量,但我希望天线的编号在另一个文件中只出现一次。最大天线数为10.
我所做的是从第5行开始的列中读取文件。就像我只想看到天线数量出现的行所示,我已经把条件的长度必须大于3的条件。这是我写的代码,但没有写在我的new_file中:
with open('file') as f1:
with open('new_file','a') as f2:
for i in range(1,11):
for line in f1.readlines()[4:]:
columns = line.split()
if len(columns) > 3 and columns[1] == i:
f2.write(i+'\n')
break
我认为问题可能出在与i匹配的天线数量的情况下,但我不知道为什么......我做错了什么?
答案 0 :(得分:2)
for i in range(1,11):
for line in f1.readlines()[4:]:
这样做是“尝试读取文件中的所有行10次”。这听起来不正确......
if len(columns) > 3 and columns[1] == i:
所以i
是行计数(由于第一个问题它不起作用,但我们假设它确实如此)并且您使用它来选择列?这也听起来不对。
也许是这样的(未经测试):
f1 = open('file');
f2 = open('new_file', 'a');
for line in f1.readlines()[4:]:
columns = line.split()
if len(columns) > 3:
f2.write(columns[0]+'\n')
将来我建议在代码中添加调试打印,这通常会有所帮助。
答案 1 :(得分:2)
有一些事情需要解决。我将首先纠正类型/代码错误,然后解决算法本身。
对于初学者来说,每次调用f1.readlines()时,它都会从中断读取的位置读取。因此,在第一次读取后,您只能获取文件的其余部分而不是整个文件。您需要做的是将文件的内容存储在循环外的列表中,然后以与当前相同的方式循环,除了来自此列表而不是文件的行。
接下来,你试图将一个字符串与列[1] == i中的整数进行比较,你必须将一个字符串转换为另一个,所以在比较中可能是int(columns [1])== i
当您尝试写入输出文件时会发生类似的错误,您必须将i转换为字符串才能向其添加'\ n',因此类似于f2.write(str(i)+'\ n')会这样做。
带有这些更改的结果代码将是:
f1=open('file')
contents=f1.readlines()[4:]
f1.close() #we don't need it anymore
with open('new_file','a') as f2:
for i in range(1,11):
for line in contents:
columns = line.split()
if len(columns) > 3 and int(columns[1]) == i:
f2.write(str(i)+'\n')
break
它似乎可以在我的机器上运行。
您正在做的是选择天线编号,然后浏览整个文件以查看是否存在具有该天线编号的线路。这当然是一种方法,但如果您打算对大型文件进行此类处理,则此算法将花费相当长的时间。另一种更有效的方法是使用集合。
Python有一个set()函数,它创建一个空集,然后使用add()函数将元素添加到集合中。
所以你最终可能会做这样的事情:
antennae=set()
f1=open('file')
lineno=1
for line in f1:
if lineno >= 5:
row = line.split()
if len(row) > 3:
antennae.add(int(row[1]))
lineno+=1
f1.close()
f2=open('new_file','a')
for antenna in antennae:
f2.write(str(antenna)+'\n')
f2.close()
这个版本在内存和时间上都很有效,因为我们只需要读取行(我们使用python的高效读取算法),同时也只检查每行一次而不是每个天线值一次。