Search code examples
pythonif-statementsplitmatchstartswith

Double if conditional in the line.startswith strategy


I have a data.dat file with this format:

REAL PART 

FREQ     1.6     5.4     2.1    13.15    13.15    17.71
FREQ     51.64   51.64   82.11  133.15   133.15   167.71

.
.
.

IMAGINARY PART 

FREQ     51.64    51.64     82.12   132.15    129.15    161.71
FREQ     5.64     51.64     83.09   131.15    120.15    160.7

.
.
.

REAL PART 

FREQ     1.6     5.4     2.1    13.15    15.15    17.71
FREQ     51.64   57.64   82.11  183.15   133.15   167.71

.
.
.

IMAGINARY PART 

FREQ     53.64    53.64     81.12   132.15    129.15    161.71
FREQ     5.64     55.64     83.09   131.15    120.15    160.7

All over the document REAL and IMAGINARY blocks are reported

Within the REAL PART block,

I would like to split each line that starts with FREQ.

I have managed to:

1) split lines and extract the value of FREQ and

2) append this result to a list of lists, and

3) create a final list, All_frequencies:

FREQ = []
fname ='data.dat'
f = open(fname, 'r')
for line in f:
    if line.startswith(' FREQ'):
    FREQS = line.split()
    FREQ.append(FREQS)

print 'Final FREQ = ', FREQ
All_frequencies = list(itertools.chain.from_iterable(FREQ))
print 'All_frequencies = ', All_frequencies

The problem with this code is that it also extracts the IMAGINARY PART values of FREQ. Only the REAL PART values of FREQ would have to be extracted.

I have tried to make something like:

if line.startswith('REAL PART'):
   if line.startswith('IMAGINARY PART'):
      code...

or:

if line.startswith(' REAL') and line.startswith(' FREQ'):
   code...

But this does not work. I would appreciate if you could help me


Solution

  • It appears based on the sample data in the question that lines starting with 'REAL' or 'IMAGINARY' don't have any data on them, they just mark the beginning of a block. If that's the case (and you don't go changing the question again), you just need to keep track of which block you're in. You can also use yield instead of building up an ever-larger list of frequencies, as long as this code is in a function.

    def read_real_parts(fname):
        f = open(fname, 'r')
        real_part = False
        for line in f:
            if line.startswith(' REAL'):
                real_part = True
            elif line.startswith(' IMAGINARY'):
                real_part = False
            elif line.startswith(' FREQ') and real_part:
                FREQS = line.split()
                yield FREQS
    
    FREQ = read_real_parts('data.dat') #this gives you a generator
    All_frequencies = list(itertools.chain.from_iterable(FREQ)) #then convert to list