迭代文件并使用 python 比较值

Iterating on a file and comparing values using python

我有一段代码可以打开包含波数和强度信息的文件,如下所示:

500.21506 -0.00134
500.45613 0.00231
500.69720 -0.00187
500.93826 0.00129
501.17933 -0.00049
501.42040 0.00028
501.66147 0.00114
501.90253 -0.00036
502.14360 0.00247

我的代码试图解析两个给定波长之间的信息:lowwav 和 highwav。我只想打印介于 lowwav 和 highwav 之间的波数强度。我的整个代码如下所示:

import datetime
import glob
path = '/Users/140803/*' 
files = glob.glob(path)

for line in open('sfit4.ctl', 'r'): 
            x = line.strip()
            if x.startswith('band.1.nu_start'):
                a,b = x.split('=')
                b = float(b)
                b = "{0:.3f}".format(b)
                lowwav = b
            if x.startswith('band.1.nu_stop'):
                a,b = x.split('=')
                b = float(b)
                b = "{0:.3f}".format(b)
                highwav = b 

with open('\_spec_final.t15', 'w') as f:
    with open('info.txt', 'rt') as infofile:
        for count, line in enumerate(infofile): 
            lat = float(line[88:94]) 
            lon = float(line[119:127])
            year = int(line[190:194])
            month = int(line[195:197])
            day = int(line[198:200])
            hour = int(line[201:203])
            minute = int(line[204:206])
            second = int(line[207:209])
            dur = float(line[302:315])
            numpoints = float(line[655:660])
            fov = line[481:497] # field of view?
            sza = float(line[418:426])
            snr = 0.0000 
            roe = 6396.2 
            res = 0.5000
            lowwav = float(lowwav)
            highwav = float(highwav)
            spacebw = (highwav - lowwav)/ numpoints

            d = datetime.datetime(year, month, day, hour, minute, second)
            f.write('{:>12.5f}{:>12.5f}{:>12.5f}{:>12.5f}{:>8.1f}'.format(sza,roe,lat,lon,snr)) # line 1
            f.write("\n")
            f.write('{:>10d}{:>5d}{:>5d}{:>5d}{:>5d}{:>5d}'.format(year,month,day,hour,minute,second)) # line 2
            f.write("\n")
            f.write( ('{:%Y/%m/%d %H:%M:%S}'.format(d)) + "UT Solar Azimuth:" + ('{:>6.3f}'.format(sza)) + " Resolution:" + ('{:>6.4f}'.format(res)) + " Duration:" + ('{:>6.2f}'.format(dur))) # line 3
            f.write("\n")
            f.write('{:>21.13f}{:>26.13f}{:>24.17e}{:>12f}'.format(lowwav,highwav,spacebw,numpoints)) # line 4
            f.write("\n")


            with open(files[count], 'r') as g:
                for line in g:
                    wave_no, tensity = [float(item) for item in line.split()]
                    if lowwav <= wave_no <= highwav :
                        f.write(str(tensity) + '\n')


g.close()        
f.close()
infofile.close()

现在,除了最后一部分我比较波长并打印出与 lowwav 和 highwav 之间的波长对应的强度外,一切正常。没有强度打印到输出文件中。

问题是,当您遍历文件 g 时,实际上是在移动它的 "file pointer"。所以第二个循环在开头找到文件并且不产生任何值。

其次,您正在生成所有这些 nums 列表,但是 lop 的每次迭代都隐藏了先前的值,使其无法访问。

您想要收集所有值然后迭代这些值:

with open(files[count], 'r') as g:
    all_nums = []
    for line in g:
        all_nums.append([float(item) for item in line.split()])

    for nums in all_nums:
        if (lowwav - nums[0]) < 0 or (highwav - nums[0]) > 0 :
            f.write(str(nums[1]))
            f.write('\n')
        else: break 

或者只在第一个循环中执行所有操作(这应该更有效率):

with open(files[count], 'r') as g:
    for line in g:
        nums = [float(item) for item in line.split()]
        if (lowwav - nums[0]) < 0 or (highwav - nums[0]) > 0 :
            f.write(str(nums[1]))
            f.write('\n')
        else: break 

另请注意,当条件第一次为假时,break 语句将停止对值的处理,您可能希望将其删除。


这就是说,请注意,您的代码会打印所有 nums[0] 大于 lowwav 或小于 highwav 的值,这意味着如果 lowwav < highwav every 数字值将被打印。如果你想检查它们是否在 lowwavhighwav 之间,你可能想使用 and 代替 or。此外,在 python 中,您可以为此编写 lowwav < nums[0] < highwav

我个人会使用以下内容:

with open(files[count], 'r') as g:
    for line in g:
        wave_no, intensity = [float(item) for item in line.split()]
        if lowwav < wave_no < highwav:
            f.write(str(intensity)+'\n')

用白色space拆分每一行,将拆分列表解压为两个名称wavelengthintensity

[line.split() for line in r] 使

500.21506 -0.00134
500.45613 0.00231

[['500.21506', '-0.00134'], ['500.45613', '0.00231']]

这个列表[(wavelength, intensity) for wavelength,intensity in lol if low <= float(wavelength) <= high]returns

[('500.21506', '-0.00134'), ('500.45613', '0.00231')]

如果你加入他们 [' '.join((w, i)) for w,i in [('500.21506', '-0.00134'), ('500.45613', '0.00231')] 你会得到 ['500.21506 -0.00134', '500.45613 0.00231']

使用listcomp过滤掉波长。并将 wavelengthintensity 连接回字符串并写入文件。

with open('data.txt', 'r') as r, open('\_spec_final.t15', 'w') as w:
    lol = (line.split() for line in r)
    intensities = (' '.join((wavelength, intensity)) for wavelength,intensity in lol if low <= float(wavelength) <= high)
    w.writelines(intensities)

如果你想输出到终端做print(list(intensities))而不是w.writelines(intensities)
data.txt;

的内容
500.21506 -0.00134
500.45613 0.00231
500.69720 -0.00187
500.93826 0.00129
501.17933 -0.00049
501.42040 0.00028
501.66147 0.00114
501.90253 -0.00036
502.14360 0.00247

low为500且high为50时输出`;

['500.21506 -0.00134', '500.45613 0.00231']