0

I have a file like this

Daniel 400 411 f
Mark 976 315 g

I would like to add 20 to line[2] and subtract 20 from line[1] and print new results overwriting this lines or to a new file.This is my try.

f=open('w', 'r')
r = open('w2','a')
lines=f.readlines()
for line in lines:
  new_list = line.rstrip('\r\n').split('\t')
  q_start=int(new_list[1]) - 20
  q_end=int(new_list[2]) + 20
  # I think something is missing here, but I don't know what
  r.writelines(lines)
f.close()
r.close()

Expected outcome

Daniel 380 431 f
Mark 956 335 g
asongtoruin
  • 9,794
  • 3
  • 36
  • 47
user3224522
  • 1,119
  • 8
  • 19

3 Answers3

4
f=open('w', 'r')
r=open('w2','a')
lines=f.readlines()

for line in lines:
    new_list = line.rstrip('\r\n').split('\t')
    new_list[1] = str(int(new_list[1]) - 20)
    new_list[2] = str(int(new_list[2]) + 20)
    r.write("\t".join(new_list)+"\n")

f.close()
r.close()

This should works. Basically, you need split your line into segments first, then modify the parts you want, and stitch them together.

Zixian Cai
  • 945
  • 1
  • 10
  • 17
  • I tried smth similar like this using join but did not work, probably I made some mistake. Anyway your's is working, thanks! – user3224522 Oct 07 '16 at 11:29
  • 1
    And you can also try the `with` syntax in Ami Tavory's answer. It's more convenient and safer in case you forget to close the files. – Zixian Cai Oct 07 '16 at 11:31
3

There's really no need to read in all the lines into memory, then loop over them. It just lengthens the code and is less efficient. Instead, try

with open('w2','w') as out:
    for line in open('w', 'r'):
        new_list = line.rstrip('\r\n').split('\t')
        q_start=int(new_list[1]) - 20
        q_end=int(new_list[2]) + 20
        out.write('\t'.join([line[0], str(q_start), str(q_end), line[3]]) + '\n')

Note the use of with to open 'w2', and the more efficient loop over the 'w''s lines.


Edit Addressing Comment

Note that if you have multiple columns (but still need to update only those at columns at 1 and 2), you can change the last line to

        out.write('\t'.join([line[0], str(q_start), str(q_end)] + line[3: ]) + '\n')
Community
  • 1
  • 1
Ami Tavory
  • 74,578
  • 11
  • 141
  • 185
1

I see that you have already accepted an answer, but still, here is my comment. There are a couple of mistakes in your code. The first is that even though you calculate the values correctly, you store them into two variable(q_start and q_end) that are not used afterwards.

The second mistake is that you write to the output file the unaltered original data (the lines list) and do so inside the loop (check your identations). hence, I believe that your output was an N repetition of the original file, where N is the number of lines in it.

The possible thirs mistake is using 'a' to open the output file. If there was any content in it, it would not be deleted. Since I am not sure of your intentions, this may not be a mistake, but pay attention if you wanted a clean slate or not.

Finally, here is my version of your code, minimally altered to work. I left the 'a' in the output file open process because I did not know if you did this on purpose.

f=open('w.txt', 'r')
r = open('w2.txt','a')
lines=f.readlines()
for line in lines:
  print line  
  new_list = line.rstrip('\r\n').split(' ')
  new_list[1]=str(int(new_list[1]) - 20)
  new_list[2]=str(int(new_list[2]) + 20)  
  r.write('\t'.join(new_list)+"\n")
f.close()
r.close()

I hope this helps.

rlinden
  • 2,053
  • 1
  • 12
  • 13