Python string processing based on the numeric part: '5a + 6b' + '2a + 3b + 9c' = '7a + 9b + 9c'

I need to add two simple polynomials (represented as strings). The following example would clarify my requirement.

input1 = '5a+6b' input2 = '2a+3b+9c' 

The required amount should be as follows:

  '7a+9b+9c' 

Currently, I have created a function (of 20 lines) to perform this task for me, but I think it can be improved.

EDIT: Adding Code

 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 
+4
source share
6 answers

You can use sympy:

 >>> 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 

Or write a simple parser:

 >>> 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' 
+4
source

sympy fits what you want

 >>> import sympy >>> a,b,c = sympy.symbols('abc') >>> 5*a+6*b + 2*a+9*b+9*c 7*a + 9*c + 15*b 
+8
source

For 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' 
+4
source

It depends on what types of expressions you want to support. If there are brackets and other constructions, this turns into a standard analysis of expressions - lexical analysis and parsing. You can simply build the appropriate abstract syntax tree and provide suitable rules for evaluation.

+3
source

Not knowing what you already have, I will simply post a description of how I approach this:

  • Convert each entry into a dictionary in the form {'a': 5, 'b': 6} 1
  • Iterate the dictionary input2 and add values ​​to the corresponding key in input1
  • Convert dictionary to string.

1) You can use the following (assumption: single letters):

 d = {} for e in input1.split("+"): d[e[:-1]] = e[-1] 
+2
source

if you are willing to sacrifice a little speed for massive control gain, I would suggest regular expressions:

 from re import findall def make_poly(s): m = findall('([+-]?[0-9.]+)([az]+)', 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} 

Some switching is still required for cross frames and incorrect user input, but it still works

+1
source

All Articles