Splitting a string into new lines based on specific number of characters

Question:

I would need to split a string in new lines based on the number of characters included in a list:

num_char=[14,12,7] # the list is actually longer: this is just an example
text = "Hello everyone how are you? R u ok?"

My expected output would be:

text = "Hello everyone
        how are you?
        R u ok?"

I tried as follows:

def chunks(s,mylist):
    x=0
    for n in mylist:
         print(n)
         for start in range(x,len(s),n):
                x=n
                yield s[start:start+x]

for chunk in chunks(text, num_char):
    print (chunk)

But it repeats the text for each element in num_char, not properly splitting into new lines.
Can you have a look at it and let me know what I am doing wrong? Thanks

Asked By: Math

||

Answers:

I think you had the right ideas, but made it too complicated by mixing two separate approaches together.

The simpler approach would be to use string slicing and a single loop. For this, you need to accumulate the respective start indices:

def chunks(s, mylist):
    start = 0
    for n in mylist:
        end = start + n
        yield s[start:end]
        start = end

The other approach would be to use an inner iterator to yield individual characters, instead of slicing. One of several possible variations of this would be:

def chunks(s, mylist):
    s_iter = iter(s)

    def chunk(n):
        for _ in range(n):
            yield next(s_iter)

    for n in mylist:
        yield ''.join(chunk(n))
Answered By: mkrieger1

itertools.islice allows you to get the needed slices:

from itertools import islice
...
it_text = iter(text)  # iterator of chars

for p in num_char:
    print(''.join(islice(it_text, p + 1)))

Hello everyone 
how are you? 
R u ok?
Answered By: RomanPerekhrest

Following your approach, isn’t a good usecase for wrap ?

from textwrap import wrap
​
num_char = [14, 12, 7]
text = "Hello everyone how are you? R u ok?"
​
def make_chunks(text, widths):
    chunks = []
    start = 0
    for width in widths:
        chunk_lines = wrap(text[start:], width=width)
        if chunk_lines:
            chunks.append(chunk_lines[0])
            start += len(chunk_lines[0]) + 1
        else:
            break
    return "n".join(lines)


Output :

>>> print(make_chunks(text, num_char))

Hello everyone
how are you?
R u ok?
Answered By: Timeless
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.