Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中动态替换字符串_Python_String_Scipy - Fatal编程技术网

在Python中动态替换字符串

在Python中动态替换字符串,python,string,scipy,Python,String,Scipy,我有用字符串写的多变量的数学函数;这些变量具有以下自变量的符号约定: 例如: f_sym_st="(sin(x0))**2+exp(x1)*cos(x2)" 我在不同的计算中使用这些。为了使用scipy的最小化例程 需要x的约定 f_opt_st="(sin(x[0]))**2+exp(x[1])*cos(x[2])" 我用 这是可行的,但我正在寻找更有活力的东西。如果f_sym来自另一个脚本,并且具有(例如)21个自变量,该怎么办 “想法”: f_opt_st=f_sym_st 这是一个示

我有用字符串写的多变量的数学函数;这些变量具有以下自变量的符号约定:

例如:

f_sym_st="(sin(x0))**2+exp(x1)*cos(x2)"
我在不同的计算中使用这些。为了使用scipy的最小化例程 需要x的约定

f_opt_st="(sin(x[0]))**2+exp(x[1])*cos(x[2])"
我用

这是可行的,但我正在寻找更有活力的东西。如果f_sym来自另一个脚本,并且具有(例如)21个自变量,该怎么办

“想法”:

f_opt_st=f_sym_st

这是一个示例-基本上我想知道是否有一种方法可以动态替换字符串?

使用格式工具:

for i in range(0,21,1):
    f_sym_st=f_sym_st.replace("x{0}".format(i),"x[{0}]".format(i))
您可以使用库中的函数:

模式
r“\bx(\d+)
匹配单词边界,后跟字母
x
,然后是数字序列。
\d+
周围的括号将数字保存为一个组。该组在替换字符串中被引用为
\1

如果要将索引降低一,可以将替换字符串更改为
r“x[\1-1]”
。例如

In [56]: s = "x1*sin(x2) + x10"

In [57]: re.sub(r"\bx(\d+)", r"x[\1-1]", s)
Out[57]: 'x[1-1]*sin(x[2-1]) + x[10-1]'
因为这只是一个字符串替换,所以它不会将
1-1
简化为
0

如果您不希望所有这些
-1
都在那里,那么您可能不会使用
re.sub
。相反,您可以执行如下操作,其中使用
re.findall
查找表达式中使用的索引:

In [132]: s = "x1*sin(x2) + x10*cos(x2)"

In [133]: indices = sorted(set(int(n) for n in re.findall(r'\bx(\d+)', s)), reverse=True)

In [134]: indices
Out[134]: [10, 2, 1]

In [135]: t = s[:]  # Make a copy of s.

In [136]: for ind in indices:
   .....:     t = t.replace('x' + str(ind), 'x[' + str(ind-1) + ']')
   .....:     

In [137]: t
Out[137]: 'x[0]*sin(x[1]) + x[9]*cos(x[1])'
如果愿意,可以将
for
循环更改为使用
格式
方法:

In [140]: for ind in indices:
   .....:     t = t.replace("x{0}".format(ind), "x[{0}]".format(ind-1))
   .....:     

反转范围,否则
x10
变为
x[1]0
。如果我想将索引降低1怎么办?例如:x1应该变成x[0]等等?我在我的答案中添加了更多的变体。我想知道你为什么在[133]中的
中使用“reverse”-“for”不需要这个顺序-或者我误解了你的意图@WarrenWeckesserI使用了
reverse=True
,因此首先处理更多数字。如果
1
是在
10
之前处理的,
x10
将转换为
x[0]0
。(见我对@klashxx答案的评论。)
In [56]: s = "x1*sin(x2) + x10"

In [57]: re.sub(r"\bx(\d+)", r"x[\1-1]", s)
Out[57]: 'x[1-1]*sin(x[2-1]) + x[10-1]'
In [132]: s = "x1*sin(x2) + x10*cos(x2)"

In [133]: indices = sorted(set(int(n) for n in re.findall(r'\bx(\d+)', s)), reverse=True)

In [134]: indices
Out[134]: [10, 2, 1]

In [135]: t = s[:]  # Make a copy of s.

In [136]: for ind in indices:
   .....:     t = t.replace('x' + str(ind), 'x[' + str(ind-1) + ']')
   .....:     

In [137]: t
Out[137]: 'x[0]*sin(x[1]) + x[9]*cos(x[1])'
In [140]: for ind in indices:
   .....:     t = t.replace("x{0}".format(ind), "x[{0}]".format(ind-1))
   .....: