Riccardo Volpe
Riccardo Volpe

Reputation: 1623

Index breaks in a set

I'm writing a python script that takes a text file like the following as input:

0   A   (*) Begin
1   A
2   A
3   A
4   A
5   A   (*) End
0   B   (*) Begin
1   B
2   B
3   B
4   B
5   B
6   B   (*) End
0   B   (*) Begin
1   B
2   B   (*) End
0   B   (*) Begin
1   B
2   B
3   B
4   B   (*) End

Now I'd like to receive the output like this one:

0   A   (*) Begin [0]
1   A
2   A
3   A
4   A
5   A   (*) End [0]
0   B   (*) Begin [0]
1   B
2   B
3   B
4   B
5   B
6   B   (*) End [0]
0   B   (*) Begin [1]
1   B
2   B   (*) End [1]
0   B   (*) Begin [2]
1   B
2   B
3   B
4   B   (*) End [2]

that would be the translation of:

>>>A = [0,1,2,3,4,5]
>>>A
[0, 1, 2, 3, 4, 5]
>>>len(A)
6
>>>B = [(0,1,2,3,4,5,6), (0,1,2), (0,1,2,3,4)]
>>>B
[(0,1,2,3,4,5,6), (0,1,2), (0,1,2,3,4)]
>>>len(B[0])
7
>>>len(B[1])
3
>>>len(B[2])
5

I tried for now in this way:

import sys, os
import os.path

txtdir = os.path.dirname(os.path.abspath(__file__))
path = os.path.join(txtdir, 'txt/')

textfile = "%sfile.txt" % (path)
with open(textfile,"r") as f:
    # read a LIST of rows into "data"
    data = f.readlines()

previous_col = ''
current_col = ''
for row in data:
    match_1 = "(*) Begin"
    match_2 = "(*) End"
    if (match_1 in row or match_2 in row):
        col = row.split()
        print col
        print len(col)

        if (col[3] == "End"):
            previous_col = col[1]
        elif (col[3] == "Begin"):
            current_col = col[1]

        i = 0
        if current_col:
            if (col[3] == "Begin" and current_col == previous_col):
                i += 1 # increment
                col[3] = "Begin [%s]" % (i)
            else:
                col[3] = "Begin [0]"

# and write everything back
with open(textfile, 'w') as f:
    f.writelines( data )

# close f file
f.close()

But there is no change into "file.txt"

May you suggest me something?

Thanks a lot,

Riccardo

Upvotes: 1

Views: 73

Answers (2)

Paul Lo
Paul Lo

Reputation: 6138

You made lots of work in for row in data, but you didn't really make any changes on data (or row), you just write the origin stuff back to the file again, that's why it looks like nothing has changed. And your modification on col which comes from col = row.split(), that would not change row and data as well.

Without changing too much on your code, you probably want to fix it by this way which use another list for saving the updated lines:

textfile = "%sfile.txt" % (path)
with open(textfile,"r") as f:
    # read a LIST of rows into "data"
    data = f.readlines()
previous_col = ''
current_col = ''
lst = list()  # for the new content you are going to override
for row in data:
    match_1 = "(*) Begin"
    match_2 = "(*) End"
    if (match_1 in row or match_2 in row):
        col = row.split()
        if (col[3] == "End"):
            previous_col = col[1]
        elif (col[3] == "Begin"):
            current_col = col[1]

        i = 0
        if current_col:
            if (col[3] == "Begin" and current_col == previous_col):
                i += 1 # increment
                col[3] = "Begin [%s]" % (i)
            else:
                col[3] = "Begin [0]"

        lst.append(' '.join(col)) # you can adjust it to the behavior you need
   else:  # append original line
        lst.append(row)  

# and write everything back
with open(textfile, 'w') as f:
    for line in lst:  # write the element in lst to the file
          f.writelines(line)
          f.writelines('\n')  

Upvotes: 2

Ashwini Chaudhary
Ashwini Chaudhary

Reputation: 250961

Apart from the obvious issue pointed out by Paul Lo that you're not updating data list at all, you're in my opinion over-complicating this stuff, you can do this simply using collections.Counter:

from collections import Counter

c = Counter()

with open('file.txt') as f, open('outfile.txt', 'w') as out:
    for line in f:
        # In `if` and `elif`, use the current value of the counter
        # for the second column, default is 0.   
        if '(*) Begin' in line:
            text = line.split(None, 2)[1]
            out.write('{}[{}]\n'.format(line.strip(), c[text]))
        elif '(*) End' in line:
            text = line.split(None, 2)[1]
            out.write('{}[{}]\n'.format(line.strip(), c[text]))
            # End found, so now increment the counter  
            c[text] += 1
        else:
            out.write(line)

Also to modify the same file in-place I would recommend using the fileinput module:

from collections import Counter
import fileinput

c = Counter()

for line in  fileinput.input('file1.txt', inplace=True):
    if '(*) Begin' in line:
        text = line.split(None, 2)[1]
        print '{}[{}]'.format(line.strip(), c[text])
    elif '(*) End' in line:
        text = line.split(None, 2)[1]
        print '{}[{}]'.format(line.strip(), c[text])
        # End found, so now increment the counter  
        c[text] += 1
    else:
        print line,

Output:

0   A   (*) Begin[0]
1   A
2   A
3   A
4   A
5   A   (*) End[0]
0   B   (*) Begin[0]
1   B
2   B
3   B
4   B
5   B
6   B   (*) End[0]
0   B   (*) Begin[1]
1   B
2   B   (*) End[1]
0   B   (*) Begin[2]
1   B
2   B
3   B
4   B   (*) End[2]

Upvotes: 2

Related Questions