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') --> 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.