0

this is my first question in this form.

For example : I have this string === 294216673539910447 And have this list of numbers === [3, 2, 3, 3, 2, 2, 3] I need the output === [294, 21, 667, 353, 99, 10, 447]

All what I found in the form is spliting by x, but nothing about multi x

  • 1
    Welcome to Stack Overflow, Please show us what you have tried. – jizhihaoSAMA Aug 31 '20 at 03:09
  • Related: [Splitting a string by list of indices](https://stackoverflow.com/q/10851445/4518341) – wjandrea Aug 31 '20 at 03:41
  • First of all, I think 23 is wrong. I presume the output is supposed to be 21. I will give you a hint. You'll need a loop. Give it a try and show us what you got. :) – brilam Aug 31 '20 at 03:11

5 Answers5

2

Try this:

def split(s, len_arr):
    res = []
    start = 0
    for part_len in len_arr:
        res.append(s[start:start+part_len])
        start += part_len
    return res

> split("294216673539910447", [3, 2, 3, 3, 2, 2, 3])
> ['294', '21', '667', '353', '99', '10', '447']
Lixin Wei
  • 441
  • 5
  • 17
2

There is no multisplit in Python, so it's a good occasion to implement it yourself.

I know a functional way how I would go using numpy and I'll try to repeat the same steps using Python purely:

from itertools import accumulate
s = '294216673539910447'
numbers = [3, 2, 3, 3, 2, 2, 3]
idx = list(accumulate(numbers, initial=0))
print([s[i:j] for i,j in zip(idx[:-1], idx[1:])])

This illustrates a beautiful way to apply cumulative sums. accumulate calculates index positions and they are [0, 3, 5, 8, 11, 13, 15, 18]. So you need to arrange them properly to get slices 0:3, 3:5, ..., 15:18.

Output
['294', '21', '667', '353', '99', '10', '447']
mathfux
  • 5,759
  • 1
  • 14
  • 34
1

Use an iterator, and use "".join() to concate them,like:

def split(s, arr):
    iterator = iter(s)
    return ["".join(next(iterator) for _ in range(length)) for length in arr]

print(split('294216673539910447', [3, 2, 3, 3, 2, 2, 3]))

Result:

['294', '21', '667', '353', '99', '10', '447']
jizhihaoSAMA
  • 12,336
  • 9
  • 27
  • 49
1

Another approach would be - Converting to String and splitting by index.

In Python, it can be done in the following way,

number = str(294216673539910447)
split = [3, 2, 3, 3, 2, 2, 3]
count = 0
result = []
for s in split:
    result.append(int(number[count:s+count]))
    count += s
print(result)

which gives output:

[294, 21, 667, 353, 99, 10, 447]
wjandrea
  • 28,235
  • 9
  • 60
  • 81
код е
  • 196
  • 2
  • 11
1

I wrote a function that can do this, flexibly and with different kinds of input

import itertools

def splits(sequence, indexes, relative=False):
    """
    Split sequence at each index in "indexes".

    If "relative" is True, each index is taken as relative to the previous one.

    >>> list(splits('hello world', [3, 6]))
    ['hel', 'lo ', 'world']
    >>> list(splits('hello world', [3, 3], relative=True))
    ['hel', 'lo ', 'world']
    """
    if relative:
        indexes = itertools.accumulate(indexes)
    start = None
    for stop in itertools.chain(indexes, [None]):
        yield sequence[start:stop]
        start = stop  # For next loop

In practice:

>>> list(splits('294216673539910447', [3, 2, 3, 3, 2, 2], True))
['294', '21', '667', '353', '99', '10', '447']

Note that you don't need the last index in the input list.

wjandrea
  • 28,235
  • 9
  • 60
  • 81