87

Is there a way to take a string that is 4*x characters long, and cut it into 4 strings, each x characters long, without knowing the length of the string?

For example:

>>>x = "qwertyui"
>>>split(x, one, two, three, four)
>>>two
'er'
2
  • 3
    Can't you just ask for the length of the string with len(x)? Commented Dec 2, 2012 at 19:45
  • Eric: How could you then use that? Commented Dec 2, 2012 at 19:46

16 Answers 16

124
>>> x = "qwertyui"
>>> chunks, chunk_size = len(x), len(x)//4
>>> [ x[i:i+chunk_size] for i in range(0, chunks, chunk_size) ]
['qw', 'er', 'ty', 'ui']
Sign up to request clarification or add additional context in comments.

5 Comments

What's the value of setting chunks? It's will always be len(x)
It's for readability
textwrap.wrap comes more handy - textwrap.wrap(x, width=2, break_long_words=True, drop_whitespace=False, replace_whitespace=False)
"It's for readability." I'm all for readability, but referring to len(x) as chunks doesn't support that goal. The name "chunks" is short for "the number of chunks," right? So it should just be set to 4. And if you want to name len(x) something, name it "length."
I don't think length is better either
30
  • :param s: str; source string
  • :param w: int; width to split on

Using the textwrap module:

PyDocs-textwrap

import textwrap
def wrap(s, w):
    return textwrap.fill(s, w)

:return str:

Inspired by Alexander's Answer

PyDocs-data structures

def wrap(s, w):
    return [s[i:i + w] for i in range(0, len(s), w)]
  • :return list:

Inspired by Eric's answer

PyDocs-regex

import re
def wrap(s, w):    
    sre = re.compile(rf'(.{{{w}}})')
    return [x for x in re.split(sre, s) if x]
  • :return list:

Comments

27

I tried Alexanders answer but got this error in Python3:

TypeError: 'float' object cannot be interpreted as an integer

This is because the division operator in Python3 is returning a float. This works for me:

>>> x = "qwertyui"
>>> chunks, chunk_size = len(x), len(x)//4
>>> [ x[i:i+chunk_size] for i in range(0, chunks, chunk_size) ]
['qw', 'er', 'ty', 'ui']

Notice the // at the end of line 2, to ensure truncation to an integer.

2 Comments

You are probably using Python3, where the division operator returns a float. You can use the truncating division operator // instead of casting to integer: len(x)//4. Also, I think the cast in int(len(x)) is unnecessary.
i came up with this answer for dividing my text into two pieces but the code divide it into 3 if you change len(x)//4 to len(x)//2. So i add +1 to the end of len(x)//2. For any of you that decide to use this answer.
13
some_string="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
x=3 
res=[some_string[y-x:y] for y in range(x, len(some_string)+x,x)]
print(res)

will produce

['ABC', 'DEF', 'GHI', 'JKL', 'MNO', 'PQR', 'STU', 'VWX', 'YZ']

Comments

12

In Split string every nth character?, "the wolf" gives the most concise answer:

>>> import re
>>> re.findall('..','1234567890')
['12', '34', '56', '78', '90']

1 Comment

In all but recreational contexts, this should be avoided due to performance.
8
def split2len(s, n):
    def _f(s, n):
        while s:
            yield s[:n]
            s = s[n:]
    return list(_f(s, n))

1 Comment

Can you explain your answer please ?
7

Here is a one-liner that doesn't need to know the length of the string beforehand:

from functools import partial
from StringIO import StringIO

[l for l in iter(partial(StringIO(data).read, 4), '')]

If you have a file or socket, then you don't need the StringIO wrapper:

[l for l in iter(partial(file_like_object.read, 4), '')]

1 Comment

If you are using python3 StringIO is now in the io module.
4

Got an re trick:

In [28]: import re

In [29]: x = "qwertyui"

In [30]: [x for x in re.split(r'(\w{2})', x) if x]
Out[30]: ['qw', 'er', 'ty', 'ui']

Then be a func, it might looks like:

def split(string, split_len):
    # Regex: `r'.{1}'` for example works for all characters
    regex = r'(.{%s})' % split_len
    return [x for x in re.split(regex, string) if x]

3 Comments

This is interesting. How exactly does this regex with split work and why does it produce a leading and lagging empty match?
B.t.w. you could also do this: list(filter(None, re.split(r'(\w{2})', x)))
This also seems to work and is simpler: re.findall(r'(\w{2})', x)
4

There is a built in function in python for that

import textwrap

text = "Your Text.... and so on"
width = 5 #

textwrap.wrap(text,width)

Vualla

Comments

1

Here are two generic approaches. Probably worth adding to your own lib of reusables. First one requires the item to be sliceable and second one works with any iterables (but requires their constructor to accept iterable).

def split_bylen(item, maxlen):
    '''
    Requires item to be sliceable (with __getitem__ defined)
    '''
    return [item[ind:ind+maxlen] for ind in range(0, len(item), maxlen)]
    #You could also replace outer [ ] brackets with ( ) to use as generator.

def split_bylen_any(item, maxlen, constructor=None):
    '''
    Works with any iterables.
    Requires item's constructor to accept iterable or alternatively 
    constructor argument could be provided (otherwise use item's class)
    '''
    if constructor is None: constructor = item.__class__
    return [constructor(part) for part in zip(* ([iter(item)] * maxlen))]
    #OR: return map(constructor, zip(* ([iter(item)] * maxlen)))
    #    which would be faster if you need an iterable, not list

So, in topicstarter's case, the usage is:

string = 'Baboons love bananas'
parts = 5
splitlen = -(-len(string) // parts) # is alternative to math.ceil(len/parts)

first_method = split_bylen(string, splitlen)
#Result :['Babo', 'ons ', 'love', ' ban', 'anas']

second_method = split_bylen_any(string, splitlen, constructor=''.join)
#Result :['Babo', 'ons ', 'love', ' ban', 'anas']

Comments

1
length = 4
string = "abcdefgh"
str_dict = [ o for o in string ]
parts = [ ''.join( str_dict[ (j * length) : ( ( j + 1 ) * length ) ]   ) for j in xrange(len(string)/length  )]

1 Comment

Hi Frederico, welcome to SO! It might be worthwhile explaining why you did what you did in this answer so that newcomers to the language and ideas you have shown can understand why this is a good course of action to take.
1
# spliting a string by the length of the string

def len_split(string,sub_string):
    n,sub,str1=list(string),len(sub_string),')/^0*/-'
    for i in range(sub,len(n)+((len(n)-1)//sub),sub+1):
        n.insert(i,str1)   
    n="".join(n)
    n=n.split(str1)
    return n

x="divyansh_looking_for_intership_actively_contact_Me_here"
sub="four"
print(len_split(x,sub))

# Result-> ['divy', 'ansh', 'tiwa', 'ri_l', 'ooki', 'ng_f', 'or_i', 'nter', 'ship', '_con', 'tact', '_Me_', 'here']

Comments

0

And for dudes who prefer it to be a bit more readable:

def itersplit_into_x_chunks(string,x=10): # we assume here that x is an int and > 0
    size = len(string)
    chunksize = size//x
    for pos in range(0, size, chunksize):
        yield string[pos:pos+chunksize]

output:

>>> list(itersplit_into_x_chunks('qwertyui',x=4))
['qw', 'er', 'ty', 'ui']

Comments

0

My solution

   st =' abs de fdgh  1234 556 shg shshh'
   print st

   def splitStringMax( si, limit):
    ls = si.split()
    lo=[]
    st=''
    ln=len(ls)
    if ln==1:
        return [si]
    i=0
    for l in ls:
        st+=l
        i+=1
        if i <ln:
            lk=len(ls[i])
            if (len(st))+1+lk < limit:
                st+=' '
                continue
        lo.append(st);st=''
    return lo

   ############################

   print  splitStringMax(st,7)
   # ['abs de', 'fdgh', '1234', '556', 'shg', 'shshh']
    print  splitStringMax(st,12)

   # ['abs de fdgh', '1234 556', 'shg shshh']

1 Comment

I don't know why people are degrading answered, users have different scenario this is the scenario which I need so up vote from my side.
0
l = 'abcdefghijklmn'

def group(l,n):
    tmp = len(l)%n
    zipped = zip(*[iter(l)]*n)
    return zipped if tmp == 0 else zipped+[tuple(l[-tmp:])]

print group(l,3)

1 Comment

While this code snippet may solve the question, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. Please also try not to crowd your code with explanatory comments, this reduces the readability of both the code and the explanations!
0

The string splitting is required in many cases like where you have to sort the characters of the string given, replacing a character with an another character etc. But all these operations can be performed with the following mentioned string splitting methods.

The string splitting can be done in two ways:

  1. Slicing the given string based on the length of split.

  2. Converting the given string to a list with list(str) function, where characters of the string breakdown to form the the elements of a list. Then do the required operation and join them with 'specified character between the characters of the original string'.join(list) to get a new processed string.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.