基于数字部分的Python字符串处理:';5a和x2B;6b'+';2a和x2B;3b和x2B;9c';=';7a和x2B;9b和x2B;9c';
我需要添加两个简单的多项式(表示为字符串)。下面的例子将阐明我的要求基于数字部分的Python字符串处理:';5a和x2B;6b'+';2a和x2B;3b和x2B;9c';=';7a和x2B;9b和x2B;9c';,python,Python,我需要添加两个简单的多项式(表示为字符串)。下面的例子将阐明我的要求 input1 = '5a+6b' input2 = '2a+3b+9c' 所需金额应如下所示: '7a+9b+9c' 目前我已经创建了一个函数(20行)来为我执行这个任务,但我认为这是可以改进的 编辑:添加我的代码 def add_domain_strings(): input_list = ['5a+6b', '2a+3b+9c'] vars_dict = {} for input in inp
input1 = '5a+6b'
input2 = '2a+3b+9c'
所需金额应如下所示:
'7a+9b+9c'
目前我已经创建了一个函数(20行)来为我执行这个任务,但我认为这是可以改进的
编辑:添加我的代码
def add_domain_strings():
input_list = ['5a+6b', '2a+3b+9c']
vars_dict = {}
for input in input_list:
temp_list = input.split('+')
for i in temp_list:
split_index = None
for j in i:
if not j.isdigit():
split_index = i.index(j)
break
if i[split_index:] in vars_dict:
vars_dict[i[split_index:]] += int(i[:split_index])
else:
vars_dict[i[split_index:]] = int(i[:split_index])
sum_string = ''
for k,v in vars_dict.iteritems():
if sum_string:
sum_string += '+%s%s' % (v,k)
else:
sum_string += '%s%s' % (v,k)
return sum_string
这取决于您希望支持的表达式类型。如果有括号和其他结构,这就变成了标准的表达式解析——词法分析和句法分析。您只需构造适当的抽象语法树并提供适当的求值规则。不知道您已经得到了什么,我将发布一篇关于如何处理此问题的描述:
{'a':5,'b':6}
1的字典input2
的字典,并将值添加到input1
1) 可以使用以下内容(假设:单个字母): 与您想要的非常接近
>>> import sympy
>>> a,b,c = sympy.symbols('abc')
>>> 5*a+6*b + 2*a+9*b+9*c
7*a + 9*c + 15*b
您可以使用Symphy:
>>> import sympy
>>> from sympy import *
>>> a = Symbol('a')
>>> b = Symbol('b')
>>> c = Symbol('c')
>>> eval('5*a+6*b')
5*a + 6*b
>>> eval('5*a+6*b') + eval('2*a+3*b+9*c')
7*a + 9*b + 9*c
或者编写一个简单的解析器:
>>> input1 = '5a+6b'
>>> input2 = '2a+3b+9c'
>>> s = "+".join((input1, input2))
>>> s
'5a+6b+2a+3b+9c'
>>> d = {}
>>> for i in s.split("+"):
... d[i[-1]] = d.get(i[-1], 0) + int(i[:-1])
...
>>> d
{'a': 7, 'c': 9, 'b': 9}
>>> "+".join("".join((str(j),i)) for i, j in d.items())
'7a+9c+9b'
对于python2.7+
>>> from collections import Counter
>>> input1 = '5a+6b'
>>> input2 = '2a+3b+9c'
>>> c=Counter()
>>> for inp in input1, input2:
... c+=Counter({x[-1]:int(x[:-1]) for x in inp.split('+')})
...
>>> '+'.join("%s%s"%(v,k) for k,v in sorted(c.items()))
'7a+9b+9c'
如果您愿意牺牲一点速度来获得巨大的控制增益,我建议使用正则表达式:
from re import findall
def make_poly(s):
m = findall('([+-]?[0-9.]+)([a-z]+)', s)
return dict([(i[1], float(i[0])) for i in m])
def add_polys(*polys):
res = {}
for poly in polys:
for item in poly.iteritems():
if res.has_key(item[0]):
res[item[0]] += item[1]
else:
res[item[0]] = item[1]
return res
>>> p1 = make_poly('4x+7y+3.5z')
>>> p1
{'y': 7.0, 'x': 4.0, 'z': 3.5}
>>> p2 = make_poly('-2x+1y+0.2z')
>>> p2
{'y': 1.0, 'x': -2.0, 'z': 0.2}
>>>
>>> add_polys(p1, p2)
{'y': 8.0, 'x': 2.0, 'z': 3.7}
它仍然需要对边缘情况和格式错误的用户输入进行一些修补,但到目前为止它仍然有效。“…但我认为这可以改进”->向我们展示您的代码,以便我们可以改进它。简单的解析器对我来说是可行的。我得到了一些类似的东西,关注的是它的可读性:)@Ocaso Protal,更改了答案,现在使用切片而不是I[0],应该适用于>10,但对于负系数等,sympy是一个更好的主意。耶,sympy!这是它的一部分,顺便说一句,它还有更强大的多项式操作功能。(最好用在*尼克斯)非常好的一个。输出除外;)@Ocas,让我来解决这个问题:)
from re import findall
def make_poly(s):
m = findall('([+-]?[0-9.]+)([a-z]+)', s)
return dict([(i[1], float(i[0])) for i in m])
def add_polys(*polys):
res = {}
for poly in polys:
for item in poly.iteritems():
if res.has_key(item[0]):
res[item[0]] += item[1]
else:
res[item[0]] = item[1]
return res
>>> p1 = make_poly('4x+7y+3.5z')
>>> p1
{'y': 7.0, 'x': 4.0, 'z': 3.5}
>>> p2 = make_poly('-2x+1y+0.2z')
>>> p2
{'y': 1.0, 'x': -2.0, 'z': 0.2}
>>>
>>> add_polys(p1, p2)
{'y': 8.0, 'x': 2.0, 'z': 3.7}