3

我正在尝试使用遵循特定格式的单词在字符串中创建一些变量。

例如,我的原始字符串是:

string = '@Cost1 + (@Cost2 + @Cost3) / @Revenue1 * 1.2'

我已经创建了一个字典如下:

mydict = {'Cost1' : 10, 'Cost2' : 5, 'Cost3' : 1, 'Revenue1' : 10}

我想创建一个函数,它将@Cost1(例如)替换为: mydict.get('Cost1')以便我可以将字符串中的@视为变量的标记并在我的字典中查找值。

因此,我的意图是:

  • 用 string.replace() 函数替换 @ by mydict.get('--> 很容易
  • ')在@words 后面的字母链末尾添加-> 这个我很难实现

我正在考虑一个 for 循环,但在每个单词末尾加上 @ 之前添加“')”的逻辑上遇到了困难。也考虑过发电机,但不太确定

另外,我想添加一个检查,每个@Cost1、@Cost2 等都在我的字典中,但是我应该能够做到这一点。

欢迎对此提供任何帮助

谢谢 !

埃里克

编辑:

根据您的评论,我希望我的最终输出是:

string = mydict.get('Cost1') + ( mydict.get('Cost2') + mydict.get('Cost3') ) / mydict.get('Revenue1') * 1.2'
4

2 回答 2

4

我认为你需要捕获一个正则表达式@+字母/数字/下划线,它"@(\w+)(匹配@然后1个或多个字母/数字/下划线并用这些创建一个组)馈送到替换函数

import re
mydict = {'Cost1' : 10, 'Cost2' : 5, 'Cost3' : 1, 'Revenue1' : 10}
string = '@Cost1 + (@Cost2 + @Cost3) / @Revenue1 * 1.2'

expression = re.sub("@(\w+)",lambda m : str(mydict.get(m.group(1),0)),string)

结果:

'10 + (5 + 1) / 10 * 1.2'

这种方法效率很高,因为它使用字典查找而不是循环来替换和创建与变量一样多的字符串。

请注意,任何未知变量都会产生 0。如果您不希望使用它mydict[m.group(1)]来触发键错误。

lambda也不是强制性的。只要将match对象作为输入并返回字符串作为输出,您就可以编写一个真正的函数:

def repfunc(m)
    return str(mydict.get(m.group(1),0))

re.sub("@(\w+)",repfunc,string)

(这就是为什么我们在获取值后转换为字符串)

一旦你有了那个表达式,你就可以应用一个评估器 (eval是最简单但不太安全的,ast.literal_eval因为它不支持操作,所以不起作用,但是还有其他的,例如simpleeval第三方模块 (可以提供可以进一步简化答案的变量列表),或此处的其他示例:评估字符串中的数学表达式

于 2019-03-19T07:49:27.620 回答
1
string = '@Cost1 + (@Cost2 + @Cost3) / @Revenue1 * 1.2'
mydict = {'Cost1' : 10, 'Cost2' : 5, 'Cost3' : 1, 'Revenue1' : 10}
string = string.replace('@', '')
for i in mydict:
    string = string.replace(i, str(mydict[i]))

print(string)
print(eval(string))

输出:

10 + (5 + 1) / 10 * 1.2

10.72
于 2019-03-19T07:47:37.450 回答