Reputation: 5924
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...
Upvotes: 1
Views: 1852
Reputation: 351
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']
Upvotes: 0
Reputation: 2134
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???']
Upvotes: 1
Reputation: 67968
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']
Upvotes: 1
Reputation: 4581
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)
Upvotes: 0