基于数字部分的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}