在line.startswith策略中加倍条件

时间:2016-12-16 20:49:32

标签: python if-statement split match startswith

我有一个data.dat文件,格式为:

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

报告了所有文档REALIMAGINARY

REAL PART区块内

我想splitFREQ开头的每一行。

我设法:

1)拆分行并提取FREQ

的值

2)将此结果附加到列表列表中,并

3)创建最终列表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

此代码的问题在于它还会提取IMAGINARY PART的{​​{1}}值。只需要提取FREQ的{​​{1}}值。

我试图制作类似的东西:

REAL PART

或:

FREQ

但这不起作用。如果你能帮助我,我将不胜感激

4 个答案:

答案 0 :(得分:2)

将此视为具有两种状态的状态机。在一种状态下,当程序在开头读取一行REAL时,它进入REAL状态并聚合值。当它用IMAGINARY读取一行时,它进入备用状态并忽略值。

REAL, IMAGINARY = 1,2

FREQ = []
fname = 'data.dat'
f = open(fname)
state = None
for line in f:
    line = line.strip()
    if not line: continue
    if line.startswith('REAL'):
        state = REAL
        continue
    elif line.startswith('IMAGINARY'):
        state = IMAGINARY
        continue
    else:
        pass
    if state == IMAGINARY:
        continue
    freqs = line.split()[1:]
    FREQ.extend(freqs)

我假设你只想要数值;因此,在脚本末尾附近的 freqs 赋值结束时[:1]。

使用没有省略号行的数据文件会在FREQ中生成以下结果:

['1.6','5.4','2.1','13 .15','13 .15','17 .71','51 .64','51 .64','82 .11','133.15','133.15','167.71 ','1.6','5.4','2.1','13 .15','15 .15','17 .71','51 .64','57 .64','82 .11','183.15','133.15','167.71']

答案 1 :(得分:2)

根据问题中的示例数据显示,以'REAL''IMAGINARY'开头的行没有任何数据,它们只是标记块的开头。如果是这种情况(并且您没有再次更改问题),您只需要跟踪您所在的块。您还可以使用yield而不是构建更大的列表频率,只要此代码在函数中。

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

答案 2 :(得分:1)

我们从设置为False的标志开始。如果我们找到包含" REAL"的行,我们将其设置为True以开始复制REAL部分下面的数据,直到找到包含IMAGINARY的行,该行将标志设置为{ {1}}然后转到下一行直到另一行" REAL"找到(因此标志变回False

以简单的方式使用标志概念:

True

this.txt看起来像这样:

with open('this.txt', 'r') as content:
    my_lines = content.readlines()

f=open('another.txt', 'w')

my_real_flag = False    
for line in my_lines:
    if "REAL" in line:
        my_real_flag = True
    elif "IMAGINARY" in line:
        my_real_flag = False
    if my_real_flag:
        #do code here because we found real frequencies
        f.write(line)
    else:
         continue #because my_real_flag isn't true, so we must have found a 
f.close()

another.txt最终看起来像这样:

REAL
1
2
3
IMAGINARY
4
5
6
REAL
1
2
3
IMAGINARY
4
5
6

原始答案仅在有一个REAL部分时才有效

如果文件是"小"足以被读作一个完整的字符串,并且只有一个" IMAGINARY PART"的实例,你可以这样做:

REAL
1
2
3
REAL
1
2
3

它可以让你在" IMAGINARY PART"线。

然后,您可以将其余代码应用于此file_str字符串,该字符串仅包含实部

详细说明,file_str是一个str,它由以下内容获得:

file_str = file_str.split("IMAGINARY PART")[0]
""" block在整个堆栈交换中被引用,因此可能有比它更好的解释。我直观地将其视为

"打开一个名为' data.dat'只能读取它并将其命名为变量my_data。一旦打开,使用my_data.read()将整个文件读入str,file_str,然后关闭' data.dat' "

现在你有一个str,你可以将所有适用的str函数应用于它。

如果" IMAGINARY PART"在整个文件中经常发生或文件太大,Tadgh建议一个标志一个中断运行良好。

with open('data.dat', 'r') as my_data:
    file_str = my_data.read()

答案 3 :(得分:1)

您需要跟踪您正在查看的部分,以便使用标记执行此操作:

// reading the existing properties
FileInputStream in = new FileInputStream("propertiesFile");
Properties props = new Properties();
props.load(in);
in.close();
// writing back the properties after updation
FileOutputStream out = new FileOutputStream("propertiesFile");
props.setProperty("property", "value");
props.store(out, null);
out.close();
顺便说一句,代替section = None #will change to either "real" or "imag" for line in f: if line.startswith("IMAGINARY PART"): section = "imag" elif line.startswith('REAL PART'): section = "real" else: freqs = line.split() if section == "real": FREQ.append(freqs) #elif section == "imag": # IMAG_FREQ.append(freqs) append然后需要使用FREQ,您可能会考虑itertools.chain.from_iterable而不是extend