0

Let’s say I have this string 'foo1bar2xyz'

I know the indexes for the digits in it {'1': 3, '2': 7}

I want to form substrings of the parent string which don’t have the numbers. How would I get substrings of a string removing particular indexes?

Which in the above case which would be ['foo', 'bar', 'xyz']

Have tried this so far

def iterate_string(og_string, start, stop):
    if start == 0:
        return og_string[:stop]
    else:
        return og_string[start+1:stop]

def ret_string(S):
    digit_dict = {c:i for i,c in enumerate(S) if c.isdigit()}
    digit_positions = list(digit_dict.values())
    # return digit_positions
    substrings = []
    start_index = 0
    for position in digit_positions:
        p = iterate_string(S, start_index, position)
        substrings.append(p)
        start_index = position

    return substrings


print ret_string('foo1bar2xyz')

But this returns ['foo', 'bar']

Relevant SO questions

Tasdik Rahman
  • 2,160
  • 1
  • 25
  • 37
  • Possible duplicate of [How to split strings into text and number?](https://stackoverflow.com/questions/430079/how-to-split-strings-into-text-and-number) – Aaron Paul Jun 04 '17 at 14:34
  • In your code unless the last character is a digit it will not get desired output. You have to check after for loop if start_index is the last index. If not append the `S[start_index + 1:]`. But you might want to consider the way that is described in the answers – kuro Jun 04 '17 at 14:39

3 Answers3

4

You can do it using RE

import re
h = "foo1bar2xyz"
l = re.compile("\d").split(h)

Output:

['foo', 'bar', 'xyz']
khelili miliana
  • 3,730
  • 2
  • 15
  • 28
2

Try this:

l = re.compile("[0-9]").split(s)
fafl
  • 7,222
  • 3
  • 27
  • 50
2

If you have the indices and want to use as the input, then that's a good idea too:

def split_by_indices(s, indices):
    ends = sorted(indices.values())  # we only need the positions
    ends.append(len(s))
    substrings = []
    start = 0
    for end in ends:
        substrings.append(s[start:end])
        start = end + 1
    return substrings

Demo:

>>> split_by_indices('foo1bar2xyz', {'1': 3, '2': 7})
['foo', 'bar', 'xyz']

This ignores any actual numeric values in the input string and uses the [3, 7] positions from your dictionary only.

However, if you are currently building the {'1': 3, '2': 7} map just to split your string, it is probably easier to just use a regular expression:

import re

split_by_digits = re.compile(r'\d').split
result = split_by_digits(inputstring)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343