我有一个包含很多软件参数的文件,它看起来像是:
CMaterial::m_HurkxPrefactor=6.14
CMaterial::m_HurkxFgamma=368800
CRegion::m_FrontDiff1:
In CDiffusion: ver_num=1
CDiffusion::m_Enable=0
CDiffusion::m_Type=0
CDiffusion::m_Profile=2
CDiffusion::m_Npeak=1e+020
CDiffusion::m_Depth=1.5e-005
CDiffusion::m_Xpeak=0
CRegion::m_FrontDiff2:
In CDiffusion: ver_num=1
CDiffusion::m_Enable=0
CDiffusion::m_Type=1
CDiffusion::m_Profile=0
CDiffusion::m_Npeak=9e+016
CDiffusion::m_Depth=0.018
CDiffusion::m_Xpeak=0
(有更多行)
有几个区域,第一个“CDiffusion :: m_Enable”控制第一个区域的属性,第二个区域用于设置第二个区域。
我希望获取此文本文件并替换为我的值。 目前我知道如何使用此代码更改多个参数,但是它很难管理文件中参数的重复:
params = {'CDiffusion::m_Type': 3,
'CDiffusion::m_Depth' : 0.018
}
编辑:错过了这部分代码
lab, val = [], []
for k, v in params.items():
lab.append(k)
value.append(v)
s = f.read()
for num, val in enumerate(lab):
s = re.sub('{0}=(.?)*'.format(val), '{1}={0}'.format(value[num], val), s)
但现在我希望例如将“CDiffusion :: m_Type”更改为3,将第二个“CDiffusion :: m_Type”更改为4.
使用此参数列表并根据最后的显示进行更改。
params = {'CDiffusion::m_Type': 3,
'CDiffusion::m_Type': 4,
}
任何帮助将不胜感激,提前谢谢!
EDIT2: @JoeIddon解决方案正在发挥作用,但我想进一步推动它:
lines = open('Test4.txt').read().strip().split('\n')
params = {
'CDiffusion::m_Type': ['3', 'False' ,'4'],
'CDiffusion::m_Depth': ['5', '6', '5']
}
with open('Test4.txt', 'w') as fh:
for l in lines:
try:
k, v = l.split('=')
if params[k] != 'False':
nl = k + '=' + params[k].pop(0)
else:
nl = l
params[k].pop(0)
except (KeyError, IndexError, ValueError):
nl = l
fh.write(nl + '\n')
print(nl)
fh.closed
如果某个值在param中,我想不更改该行,在这种情况下为'false'。它似乎不起作用
答案 0 :(得分:2)
字典键必须是唯一的,以便最后一个字典无效。你真正想要的是一个字典,其中的值是列表。这将允许您按顺序指定替换应该是什么。此外,由于它们是文件中的替换,因此它们必须是字符串,而不是整数。
所以,例如:
params = {
'CDiffusion::m_Type': ['3', '4'],
'CDiffusion::m_Depth': ['5', '6']
}
现在,要按顺序执行此替换,我们无法使用.replace
,因为这会更改所有实例;相反,我们必须编写自己的方法。
为此,我们可以迭代每一行,在'='
上拆分,然后从params
检索下一个替换值。为此,我们可以弹出列表中的第一个项目(第一个替换),并在编写新行(nl
代码时)使用它。
我们需要考虑的唯一最后一件事是当密钥(因此分割的前半部分)不在我们的params
字典中时,以及它在字典中时的情况,但由于某种原因,没有替代品(即清单是空的)。这些可以分别用KeyError
和IndexError
来捕获(因此我们需要try...except
)。此外,经过测试,我意识到并非所有的行实际上都有'='
s,所以我们还需要捕获ValueError
,对于这种情况。
<强>更新强>
你非常接近尝试添加一个没有改变价值的案例,但是你有两件事是错的。
首先,由于Python列表中允许使用不同的数据类型(字符串,整数,更多列表等),因此使用False
代替'False'
可能更容易。将使检查更容易。
其次,当您检查此案例是否需要跳过(False
)时,您正在检查params[k]
。这是错误的,因为params[k]
将为我们提供替换列表,而不是 next 替换。对于下一次替换,您需要像我们一样pop(0)
。
所以,代码(params
已经定义并且更新):
lines = open('f.txt').read().strip().split('\n')
with open('f.txt', 'w') as fh:
for l in lines:
try:
k, v = l.split('=')
r = params[k].pop(0)
if r:
nl = k + '=' + r
else:
nl = l
except (KeyError, IndexError, ValueError):
nl = l
fh.write(nl + '\n')
好的,我刚试过它并且它有效;之后是文件:
CMaterial::m_HurkxPrefactor=6.14
CMaterial::m_HurkxFgamma=368800
CRegion::m_FrontDiff1:
In CDiffusion: ver_num=1
CDiffusion::m_Enable=0
CDiffusion::m_Type=3
CDiffusion::m_Profile=2
CDiffusion::m_Npeak=1e+020
CDiffusion::m_Depth=5
CDiffusion::m_Xpeak=0
CRegion::m_FrontDiff2:
In CDiffusion: ver_num=1
CDiffusion::m_Enable=0
CDiffusion::m_Type=4
CDiffusion::m_Profile=0
CDiffusion::m_Npeak=9e+016
CDiffusion::m_Depth=6
CDiffusion::m_Xpeak=0
注意第一个CDiffusion::m_Type
现在是3
,第二个是4
,以及第一个CDiffusion::m_Depth
现在是如何5
和第二个6
。