1

I know the method textwrap.wrap, but this method splits a string to a fixed length for each part, but I'm looking for a function in python that splits the string the string into fixed num of parts.

For example:string = "Hello, my name is foo"
and foo(string, 7)
returns ['Hel', 'lo,', ' my', ' na', 'me ', 'is ', 'foo']

Algorithmically, I know how to implement this method, but I want to know if there a module that provides it or a "magic function" in the regex module that answers this problem...

4
  • @Stidgeon I mentioned that I don't want the textwrap.wrap method :) Commented Feb 19, 2016 at 19:19
  • 1
    How do you want it to be handled when the string cannot be divided evenly? For example if the string length is 9 and you want 4 parts do you want the parts to have lengths [3, 2, 2, 2]? Do you want an error. Do you want the bigger piece at the beginning or end? Commented Feb 19, 2016 at 19:25
  • 1
    Voted to reopen because the linked question asked for evenly sized chunks where this question asks for a particular number of chunks. Commented Feb 19, 2016 at 19:34
  • You could textwrap.wrap(your_string, len(your_string)/number_of_chunks), depending on how you want to manage cases when the string cannot be divided in number_of_chunks parts. Commented Feb 19, 2016 at 19:38

4 Answers 4

1

One approach can be using re.

import re
string = "Hello, my name is foo"
def foo(string, parts):
    x=len(string)/parts
    print re.findall(r".{"+str(x)+r"}|.+?$",string)

foo(string,7)

Output:['Hel', 'lo,', ' my', ' na', 'me ', 'is ', 'foo']

Sign up to request clarification or add additional context in comments.

3 Comments

foo(string,6) returns the same result as foo(string,7). foo(string,5) leaves off the last letter of the sentence. (Temporary downvote until fixed. Sorry.)
@StevenRumbalski fixed.............foo(6) and foo(7) will be same .you can have 3.5 letters
Giving one extra item when the string is not evenly divisible is a surprising result. You may want to call it out in your answer.
1

I don't know if any module does this... but I feel compelled to say that the problem here is basically What is the most "pythonic" way to iterate over a list in chunks?, except you have strings instead of lists. But the most pythonic way there should also be the most pythonic here, I suppose, and it's a good thing if you can avoid re. So here is the solution (not sure what you want if the string cannot be evenly divided by the number of parts; assuming you simply discard the "remainder"):

# python 3 version
def foo(string, n):
    part_len = -(-len(string) // n)  # same as math.ceil(len(string) / n)
    return [''.join(x) for x in zip(*[iter_str] * part_len)]

Thus:

>>> s = "Hello, my name is foo"
>>> foo(s, 7)
['Hel', 'lo,', ' my', ' na', 'me ', 'is ', 'foo']
>>> foo(s, 6)
['Hell', 'o, m', 'y na', 'me i', 's fo']

Now admittedly having foo(s, 6) return a list of length 5 is somewhat surprising. Maybe you want to raise an exception instead. If you want to keep the remainder, then use zip_longest

from itertools import zip_longest

def foo2(string, n, pad=''):
    part_len = -(-len(string) // n)
    return [''.join(x) for x in zip_longest(*[iter(string)] * part_len, fillvalue=pad)]

>>> foo2(s, 6)
['Hell', 'o, m', 'y na', 'me i', 's fo', 'o']
>>> foo2(s, 6, pad='?')
['Hell', 'o, m', 'y na', 'me i', 's fo', 'o???']

Comments

0

I don't think there is a builtin, but I think you could do it with regex: https://stackoverflow.com/a/9477447/1342445

In that case your function generates the regex from the len(input) / int(parts) of the string, and raises an error if it's not divisible by the input. Would be much simpler with undefined remainder behavior :)

I think it would look something like:

import re


def split_into(string: str, parts: int):
    if (len(string) % parts) != 0:
        raise NotImplementedError('string is not divisible by # parts')

    chunk_size = len(string) / parts
    regex = '.'*chunk_size
    return re.findall(regex, string)

2 Comments

Being evenly divisible is quite the limitation, but at least you call it out.
Indeed, but the answer becomes more nuanced when you have a remainder. How do you distribute it? Chunk size becomes dynamic, rather than fixed, etc.
0

Yet another solution to this problem...

# split text to parts                                                           
def split_to_parts(txt,parts):
  # return array
  ret=[]
  # calculate part length
  part_len=int(len(txt)/parts)
  # iterate and fill the return array
  for i in range(parts):
    # divide the text
    piece=txt[part_len*i:part_len*(i+1)]
    # add it to the return array
    ret.append(piece)
  # return the array
  return(ret)

txt = "Hello, my name is foo"
parts=7    
split_to_parts(txt,parts)

# output:
# ['Hel', 'lo,', ' my', ' na', 'me ', 'is ', 'foo']

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.