Home > Net >  How to intersperse characters from two different strings alternatively to form a string
How to intersperse characters from two different strings alternatively to form a string

Time:05-23

Method1:

    abc = 'Hello World'
    qwe = 'abc 123'
    
    #intersperse words
    def intersperse(abc,qwe):
        list = []
        for i in abc:
            list.append(i)
            for j in qwe:
                list.append(j)
        return ''.join(list)
    
    intersperse(abc,qwe)

Output: "Habc 123eabc 123labc 123labc 123oabc 123 abc 123Wabc 123oabc 123rabc 123labc 123dabc 123"

Method 2:

    #intersperse words
    def intersperse(abc,qwe):
        abcs = abc.split()
        qwes = qwe.split()
        result = sum(zip(abcs, qwes [0]), ())[:-1]
        return ''.join(result)
    
    intersperse(abc,qwe)

Output: "HelloabcWorld" (<--somehow the 123 is missing)

Tried both methods but couldn't get it to work. I want the output to also take into consideration the blanks in between the characters as well.

Desired output: "Haeblcl o1 2W3orld"

CodePudding user response:

What about a simple for-loop inside a list comprehension to shorten the matter?

def intersperse(abc,qwe):
    min_len = min(len(abc), len(qwe))
    return "".join([abc[i]   qwe[i] for i in range(min_len)])   abc[min_len:]   qwe[min_len:]

Explanation: determine the min length of both strings - up to that length, alternatingly add characters of both strings. Finally, add the leftover characters of the longer string, leveraging slicing.

The output is as expected: intersperse("Hello World", "abc 123") yields 'Haeblcl o1 2W3orld'.

CodePudding user response:

from itertools import chain, zip_longest

''.join(filter(None, chain.from_iterable(zip_longest(abc, qwe))))

CodePudding user response:

It's easily done with a generator function.

abc = 'Hello World'
qwe = 'abc 123'

def intersperce(a, b):
    if len(a) > len(b):
        filler = a[len(b):]
    else:
        filler = b[len(a):]

    def generator():
        for char_a, char_b in zip(a, b):
            yield char_a
            yield char_b
        for x in filler:
            yield x

    return "".join(generator())


assert intersperce(abc, qwe) == "Haeblcl o1 2W3orld"

yield returns the value and suspend execution. Just by iterating over a zip on (a, b), you can easily yield one character at a time. Then just have to fill with the remaining characters.

You can refer to the official documentation about it!

EDIT:

I didn't know about zip_longest, thanks @Nin17. Here is a shorter version that doesn't need a filler.

from itertools import zip_longest

abc = 'Hello World'
qwe = 'abc 123'

def intersperce(a, b):

    def generator():
        for char_a, char_b in zip_longest(a, b, fillvalue=""):
            yield char_a
            yield char_b

    return "".join(generator())


assert intersperce(abc, qwe) == "Haeblcl o1 2W3orld"

which leads me to the code golf version

from itertools import zip_longest

abc = 'Hello World'
qwe = 'abc 123'


def intersperce(a, b):
    return "".join(i   j for i, j in zip_longest(a, b, fillvalue=""))


assert intersperce(abc, qwe) == "Haeblcl o1 2W3orld"

CodePudding user response:

You can use itertools zip_longest and join:

from itertools import zip_longest
abc = 'Hello World'
qwe = 'abc 123'
''.join(i j for i, j in zip_longest(abc, qwe, fillvalue=''))

Output:

'Haeblcl o1 2W3orld'

CodePudding user response:

Using zip and generator expression:

abc = 'Hello World'
qwe = 'abc 123'
min_len = min(len(abc), len(qwe))
print("".join(a q for a,q in zip(abc, qwe))   abc[min_len:]   qwe[min_len:])

(code for taking the ending of longer string from @LMD's answer)

CodePudding user response:

from itertools import zip_longest
''.join(''.join(x) for x in list(zip_longest(abc,qwe,fillvalue ='')))
  • Related