1

私は現在取り組んでいるプロジェクトのためにこれまでほとんどコーディングされたPythonスクリプトを持っており、障害にぶつかっています。私は基本的に、次の出力ファイル(big.dmpと呼ばれる)を吐き出すプログラムを実行します。

)O+_05 Big-body initial data  (WARNING: Do not delete this line!!)
) Lines beginning with `)' are ignored.
)---------------------------------------------------------------------
  style (Cartesian, Asteroidal, Cometary) = Cartesian
  epoch (in days) =    1365250.
)---------------------------------------------------------------------
COMPSTAR r=5.00000E-01 d=3.00000E+00  m= 0.160000000000000E+01
  4.570923967127310E-01  1.841433531828977E+01  0.000000000000000E+00
 -6.207379670518027E-03  1.540861575481520E-04  0.000000000000000E+00
  0.000000000000000E+00  0.000000000000000E+00  0.000000000000000E+00

このファイルでは、エポック行とCOMPSTARで始まる行の両方を編集する必要がありますが、最後の3行にはオブジェクトのデカルト座標が含まれており、基本的にプログラムが出力するものであるため、統合から統合まで残りの情報を一定に保ちます。 。

f = open('big.dmp', 'w')最初のファイルの使用方法と作成方法は知ってf.write('text here')いますが、次の統合のために、これらの最後の3行を新しいbig.dmpファイルに読み込むにはどうすればよいでしょうか。

4

4 に答える 4

1

これは、もう少し変更許容度の高いバージョンです。

import re

reg_num = r'\d+'
reg_sci = r'[-+]?\d*\.?\d+([eE][+-]?\d+)?'

def update_config(s, finds=None, replaces=None, **kwargs):
    if finds is None:    finds = update_config.finds
    if replaces is None: replaces = update_config.replaces

    for name,value in kwargs.iteritems():
        s = re.sub(finds[name], replaces[name].format(value), s)
    return s

update_config.finds = {
    'epoch': r'epoch \(in days\) =\s*'+reg_num+'\.',
    'r':     r' r\s*=\s*' + reg_sci,
    'd':     r' d\s*=\s*' + reg_sci,
    'm':     r' m\s*=\s*' + reg_sci
}
update_config.replaces = {
    'epoch': 'epoch (in days) ={:>11d}.',
    'r':     ' r={:1.5E}',
    'd':     ' d={:1.5E}',
    'm':     ' m= {:1.15E}'
}

def main():
    with open('big.dmp') as inf:
        s = inf.read()

    s = update_config(s, epoch=1365252, r=0.51, d=2.99, m=1.1)

    with open('big.dmp', 'w') as outf:
        outf.write(s)

if __name__=="__main__":
    main()
于 2012-06-30T00:04:13.540 に答える
1

ファイルの形式が行番号に関して固定されている可能性が低い場合、このソリューションは次の 2 行のみを変更します。

with open('big.dmp') as inf, open('out.txt', 'w') as outf:
    data = inf.readlines()
    data[4] = '  epoch (in days) = 9999.\n'      # line with epoch
    data[6] = 'COMPSTAR r=2201 d=3330  m= 12\n'  # line with COMPSTAR
    outf.writelines(data)

この出力ファイルは次のようになります。

)O+_05 Big-body initial data  (WARNING: Do not delete this line!!)
) Lines beginning with `)' are ignored.
)---------------------------------------------------------------------
  style (Cartesian, Asteroidal, Cometary) = Cartesian
  epoch (in days) = 9999.
)---------------------------------------------------------------------
COMPSTAR r=2201 d=3330  m= 12
  4.570923967127310E-01  1.841433531828977E+01  0.000000000000000E+00
 -6.207379670518027E-03  1.540861575481520E-04  0.000000000000000E+00
  0.000000000000000E+00  0.000000000000000E+00  0.000000000000000E+00

行番号が一貫していない場合、これは明らかに機能しませんが、行番号に関してデータ形式が一貫している場合に備えて、これを提供すると思いました。

また、ファイル全体を一度にメモリに読み込むため、本当に巨大なファイルには理想的なソリューションではありません。

を使用してファイルを開く利点はwith、作業が終了したとき、または例外が発生した場合に、ファイルが自動的に閉じられることです。

より柔軟な解決策 (文字列を検索し、ファイルを 1 行ずつ処理する) がありますが、データが固定されていて小さい場合、これらの要因を利用することのマイナス面はありません。頭のいい人がかつて「複雑よりも単純なほうがよい」と言いました。(パイソンの禅)

于 2012-06-29T22:25:15.190 に答える
1

もしかしてこういうこと?

infile = open('big1.dmp')
outfile = open('big2.dmp', 'w')

for line in infile:
    if line.startswith(')'):
        # ignore comments
        pass
    elif 'epoch' in line:
        # do something with line
        line = line.replace('epoch', 'EPOCH')
    elif line.startswith('COMPSTAR'):
        # do something with line
        line = line.replace('COMPSTAR', 'comparison star')
    outfile.write(line)
于 2012-06-29T22:15:46.540 に答える
0

何が必要かを理解するのは少し難しいですが、) で始まらない行のみを削除したいとします。

text = open(filename).read()
lines = text.split("\n")
result = [line for line in lines if not line.startswith(")")

または、ワンライナー:

[line for line in open(file_name).read().split("\n") if not line.startswith(")")]
于 2012-06-29T22:11:17.593 に答える