1

I am new to programming and I tried to split an input string as follows Ex:

string = ['1981+198-19871*1981/555'] --> ['1981','198','19871','1981','555'] 

using two for cycles and I cannot understand why it returns me an error: 'list index out of range'

operatori = ["+","-","*","/"]
string = ['1981+198-19871*1981/555']

for operatore in operatori:
   for i in range(len(string)):
        string = string[i].split(operatore)
        print(operatore)
2
  • 2
    That's an easy task for re.split: do import re and then re.split('\W+', '1981+198-19871*1981/555'). That will result in ['1981', '198', '19871', '1981', '555']. Commented Dec 22, 2019 at 11:35
  • 2
    What you try to do is not really clear, but you update string (which shouldn't be called this way, since it is actually a list) while looping. In the third loop, you start with a list of length 2, and change it to a list of length 1 after the first iteration. Commented Dec 22, 2019 at 11:37

2 Answers 2

1

Don't reinvent the wheel. Let the standard library work for you:

Python 3.7.5 (default, Dec 15 2019, 17:54:26) 
[GCC 9.2.1 20190827 (Red Hat 9.2.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> re.split('\W+', '1981+198-19871*1981/555')
['1981', '198', '19871', '1981', '555']
>>>

You can even have anything but digits as the separator:

>>> re.split('\D+', '1981+198-19871*1981/555abc12')
['1981', '198', '19871', '1981', '555', '12']
>>> 

And, finally, if you just want to split on the operators +, *, /, and -, just do:

>>> re.split('[+*/-]', '1981+198-19871*1981/555abc12')
['1981', '198', '19871', '1981', '555abc12']
>>>
Sign up to request clarification or add additional context in comments.

3 Comments

Pretty sure they only want to split on the operators, + - * /
@IşıkKaplan, that's not a problem for re.split neither. Just use [+*/-] as the regular expression.
@MrCont, No worries. My pleasure. I hope it helps.
0

Here is two methods of how you can resolve your task.

First method without importing anything and the second using re module with a list of escaped operators:

import re

operators = ['+', '-', '*', '/']
strings = ['1981+198-19871*1981/555']


def split_string(data: list, operators: list):
    for elm in data:
        out = ''
        for k in elm:
            if k not in operators:
                out += k
            else:
                yield out
                out = ''
        if out:
            yield out  # yield the last element


def re_split_string(data: list, operators: list):
    for elm in data:
        escaped = ''.join([re.escape(operator) for operator in operators])
        if escaped:
            pattern = r'[{operators}]'.format(operators=escaped)
            yield from re.split(pattern, elm)
        else:
            yield elm


first = list(split_string(strings, operators))
print(first)
second = list(re_split_string(strings, operators))
print(second)

Output:

['1981', '198', '19871', '1981', '555']
['1981', '198', '19871', '1981', '555']

PS: If you want to see the performance of each method, let's for example use a big string strings = ['1981+198-19871*1981/555' * 1000]

Results in my machine:

In [1]: %timeit split_string(strings, operators)                                                                    
211 ns ± 0.509 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [2]: %timeit re_split_string(strings, operators)                                                                 
211 ns ± 0.49 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

As you can see, the two methods have nearly the same execution time.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.