Capt.Pyrite
Capt.Pyrite

Reputation: 911

Splitting a string which contains mathematical operators in python

world!, I ran into a problem earlier today... I am trying to split operations apart from digits and variables. it'll split +,-,/,* apart from the digits or the variable (ex: 10+11+10 goes in the code and a list comes out with ["10","+","11","+","10"])

My code:

x = "100+20+a"

operators = ["*","/","+","-"]

def get_index_of(OP,txt):
  return [v for v,i in enumerate(txt+"+") if i == OP]

l = []
for i in operators:
  l.append(get_index_of(i,x))

spliting = sum(l,[])

out = []
for j in spliting:
  out.append(x)
  x = x[:j]

print(out)

The output I get:

['100+20+a', '100', '100']

The output I want:

["100","+","20","+","a"]

Upvotes: 1

Views: 492

Answers (4)

Harly Hallikas
Harly Hallikas

Reputation: 620

Well after my first comment above, I took a break. I still decided to post this regex implementation:

import re

def split_using_regex(x='', ops='*/+-'):
    r = "([0-9A-Za-z]+).?([%s]{1})" % ops
    return [s.strip() for s in re.sub(r,r"\1,\2,",x).split(",")]


>>> split_using_regex('10 - 30 / 3 + 7* c+4')
['10', '-', '30', '/', '3', '+', '7', '*', 'c', '+', '4']

>>> split_using_regex('100+20-*a')
['100', '+', '20', '*', 'a']

Upvotes: 1

DarrylG
DarrylG

Reputation: 17156

Using stack

def parse(expression, operators = ["*","/","+","-"]):
    stack = ['']               # start with empty string on stack
    for c in expression:
        if c in operators:
            stack.append(c)    # place operator as new element on stack
            stack.append('')
        elif c != " ":         # not a space
            stack[-1] += c     # append to last element on stack
            
    return stack

Example

print(parse("100+20+a"))
# Output: ['100', '+', '20', '+', 'a']

Upvotes: 3

Daniel Hao
Daniel Hao

Reputation: 4980

If you're open to 3rd party tool - there is a simple approach:

It's easy to convert to your desired function.


from more_itertools import split_at

>>>lst = list(split_at(x, lambda x: x == '+', keep_separator=True))
                       
>>>lst
                       
[['1', '0', '0'], ['+'], ['2', '0'], ['+'], ['a']]
outs = [''.join(x) for x in lst]
                       
>>>outs
                       
['100', '+', '20', '+', 'a']

# or doing in one shot:
>>>final = [''.join(x) for x in split_at(x, lambda x: x == '+', keep_separator=True)]

Upvotes: 1

Andrej Kesely
Andrej Kesely

Reputation: 195428

Try:

from itertools import groupby

x = "100+20+a"
operators = {"*", "/", "+", "-"}  # <-- use set instead of a list

out = ["".join(g) for _, g in groupby(x, operators.__contains__)]
print(out)

Prints:

['100', '+', '20', '+', 'a']

Upvotes: 1

Related Questions