Python电子表格式公式分析器?

我有一个词典列表,例如:

l =[{country:'Italy',sales:100,cost:50}{country:'Italy',sales:130,cost:60} {country:'Germany',sales:110,cost:50}] 

我想要一个Python函数,它采用类似电子表格的inputstring (请阅读下面的@lott的注释),如下所示:

 margin = (sales-cost)/sales 

这让我回想起来:

 l = [{country:'Italy',sales:100,cost:50,margin:1} ...] 

你知道任何现有的图书馆这样做吗? 或者你有一个想法如何实现它?

我已经有了一个想法,正如你可以看到下面,但我想要一个更好的方法来parsing公式。 处理“()”中的块或类似的东西。

 parsed_op = {'sales':1,'cost':-1} calc_field_name = 'smi' counter = -1 for d in data: counter = counter + 1 calc = sum([float(d[item])*parsed_op[item] for item in parsed_op]) d[calc_field_name] = calc del data[counter] data.append(d) 

在我看来,真正的问题是把数字放在有词的地方。

一种方法可以用re.sub()和一些字典格式(我不知道他们的真名,bute 这里有一些例子)

代码:

 import re dct = {'country': 'Italy', 'sales': 100, 'cost': 50} formula = 'margin = (sales-cost)/sales' res_name,operation = formula.split('=') num_formula = re.sub(r'([a-zA-Z]+)', r'{d[\1]}', operation.strip()).format(d=dct) num_formula # '(100-50)/100' dct[res_name.strip()] = eval(num_formula.format(d=dct)) 

结果:

 {'country': 'Italy', 'cost': 50, 'margin': 0.5, 'sales': 100} 

我用eval()来评估string中的数字操作。 通常使用eval()是不好的做法,但这里非常方便。

总之,我相信你可以用别的东西替代eval()评估。


快速说明

re.sub()做了什么:

 >>> re.sub(r'([a-zA-Z]+)', r'{d[\1]}', '(sales-cost)/sales') '({d[sales]}-{d[cost]})/{d[sales]}' 
  • r'([a-zA-Z]+)'是模式。
    • [a-zA-Z]匹配任何字母字符。
    • 在我们的例子中, +后面跟着匹配一个或者多个字母字符,比较乱。
    • 括号用于分组。 这意味着里面的内容将会成为一个群体。 因为我们只有一对括号,这将是第一组。
  • r'{d[\1]}'是replace。
    • \1代表“放置组号1”。
    • 所以基本上会打包与{d[ ]}匹配的内容。

要了解更多关于重新模块看看官方文档 。

格式化如何工作:

 >>> '{d[first]} + {d[second]}'.format(d=dct) '1 + 2' 

把这两个东西用一些strip()在这里和那里清理干净的string,你会得到上面的代码。

做这样的事情,你会更快乐。

 Metrics = namedtuple('Metrics', 'country,sales,cost' ) Margin = namedtuple( 'Margin', 'country,sales,cost,margin' ) metrics = ( Metrics(**row) for row in l ) # a one-use only generator; not a sequence margin = [ Margin( m.country, m.sales, m.cost, margin= (m.sales-m.cost)/m.sales ) for m in metrics ] 

这很好,因为你的公式margin= (m.sales-m.cost)/m.sales是非常非常容易阅读,理解和修改。