tags:

views:

151

answers:

3

What would be a smart way to mix two strings in python?

I need something to insert one string into another one with specified (default=1) intervals:

>>> aa = 'abcdefghijkl'
>>> bb = mix(aa)
>>> bb
'a b c d e f g h i j k l '
>>> cc = mix(bb,'\n',8)
>>> print cc
a b c d 
e f g h 
i j k l 

Is there an elegant way to write the 'mix' code, which will take 1 mandatory parameter (string to work on) and two optional: separator to insert starting from the second position inside the string (could be longer than one character, default is one space), and length of each slice of the originally passed string to insert the separator at (default is 1 -- meaning after each original symbol from the passed string there will be inserted a string which was the second parameter).

+5  A: 
def mix(s, c=' ', n=1):
    return ''.join(s[i:i+n]+c for i in range(0,len(s),n))
gnibbler
+1. That was fast and compact.
Manoj Govindan
+2  A: 

From the itertools there is the 'grouper' recipe, shown here:

def grouper(n, iterable, fillvalue=None):
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return itertools.izip_longest(fillvalue=fillvalue, *args)

Then the function you want, let's call it mix thanks to gnibbler, looks like

def mix(s, c=' ', n=1):
    return c.join(''.join(seq) for seq in grouper(n, s, '')) + c

I prefer it over gnibbler's answer because it is easier to understand (and write), as it is taken in terms of an existing grouper function which is used for things like this.

Devin Jeanpierre
+1 for explanation and clarity.
Manoj Govindan
A: 
def mix(seq,sep=' ',dist=1):
    return sep.join(seq[i*dist:i*dist+dist]
                    for i in range(len(seq)/dist+1))

def take_n(seq,n):
    for i in range(len(seq)/n+1):
        yield seq[i*n:i*n+n]

def mixit(mystring, sep=' ', dist=1):
    return sep.join(list(take_n(mystring,dist)))

aa = 'abcdefghijkl'
bb = mix(aa)
print bb
cc = mix(bb,'\n', dist=8)
print cc

print mixit(aa)
print mixit(mixit(aa),'\n',8)
Tony Veijalainen