Join strings split with the python [::n] method into one string as they were before in one line If you split a string like foobar with something like [::3], [1::3], [2::3] it will give you ['fb','oa','or']. I needed to then be able to rejoin that into foobar and I got given a challenge to make it in one line. This is my solution:

split_join = lambda t:''.join(''.join([s.ljust(len(max(t,key=len))) for s in t])[i::len(max(t,key=len))] for i in range(len(max(t,key=len)))).replace(' ','')


and I was wondering if there was any neater or shorter way to make this.

EDIT: I also want it to be able to deal with strings of uneven lengths
First, in order to make this even remotely readable, let's convert it to a function and save intermediate results (especially the reused ones) to variables:

def split_join6(table):
    cols = max(map(len, table))
    justified = ''.join([col.ljust(cols) for col in table])
    y = ''.join(justified[i::cols] for i in range(cols))
    return y.replace(' ','')


Now, what you seem to want is similar to the roundrobin recipe from itertools:


from itertools import cycle, islice

def roundrobin(*iterables):
    "roundrobin('ABC', 'D', 'EF') --&gt; A D E B F C"
    # Recipe credited to George Sakkis
    num_active = len(iterables)
    nexts = cycle(iter(it).__next__ for it in iterables)
    while num_active:
        try:
            for next in nexts:
                yield next()
        except StopIteration:
            # Remove the iterator we just exhausted from the cycle.
            num_active -= 1
            nexts = cycle(islice(nexts, num_active))



x = ['fb','oa','or']
print("".join(roundrobin(*x))
# foobar


Note that making things into one-liners can only get you so far. It does sometimes help you to learn some new concepts in a language, but quite often it makes your code unreadable. In Python you should keep your lines to 80 or 120 characters (as per Python's official style-guide, PEP8). Anything that does not fit into that is probably too complicated to understand again, even a month later.

That being said, here is a shorter one-liner, albeit with one needed import:

from itertools import zip_longest

f = lambda x: "".join(map(lambda t: "".join(filter(None, t)), zip_longest(*x)))

f(['fb','oa','or'])
# 'foobar'


The zip_longest and filter(None, ...) are only needed in case not all parts are the same length. Otherwise (which is at least true for "foobar") it would just be:

f = lambda x: "".join(map("".join, zip(*x)))


Both use the well-known trick of doing zip(*iterable) to transpose an iterable of iterables.