我有一个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
报告了所有文档REAL
和IMAGINARY
块
在REAL PART
区块内
我想split
以FREQ
开头的每一行。
我设法:
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
但这不起作用。如果你能帮助我,我将不胜感激
答案 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
如果文件是"小"足以被读作一个完整的字符串,并且只有一个" 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在整个堆栈交换中被引用,因此可能有比它更好的解释。我直观地将其视为现在你有一个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
。