ThatQuantDude
ThatQuantDude

Reputation: 833

Concatenate two lists of different length in between each other

I have two list of different sizes, n and n-1. I have to concatenate two lists that look like this

list1 = ['a','b','c']
list2 = ['-','-']

They have to be concatenated to get s.th like this

str_out = 'a-b-c'

I have tried to figure out an elegant way to do this but only managed to come up with this solution

list1 = ['a','b','c']
list2 = ['-','-']
string2 = ''

for index,item in enumerate(list1):
    string2 = string2 + item + list2[index-1]

print(string2)

which prints

'a-b-c-'

I am looking for a nicer implementation or how I can get rid of the final dash (-)

EDIT: To clarify, the lists will be dynamic and list2 can contain arbitrary characters.

e.g: list2 = ['*','-']

Upvotes: 2

Views: 4276

Answers (9)

Gennady Kandaurov
Gennady Kandaurov

Reputation: 1964

Try following:

from itertools import chain
"".join(x for x in chain(*map(None, list1, list2)) if x is not None)

Update add izip_longest version:

from itertools import chain, izip_longest
"".join(x for x in chain(*izip_longest(list1, list2)) if x is not None)

Update py3 version:

from itertools import chain, zip_longest
"".join(x for x in chain(*zip_longest(list1, list2)) if x is not None)

Upvotes: 1

MSeifert
MSeifert

Reputation: 152607

There are several external packages that have builtin functions for this kind of "interleaving" of iterables, just to show one of them: iteration_utilities.roundrobin (note, that I'm the author of this library):

>>> from iteration_utilities import ManyIterables
>>> ManyIterables(['a','b','c'], ['-','-']).roundrobin().as_string()
'a-b-c'
>>> ManyIterables(['a','b','c'], ['-','*']).roundrobin().as_string()
'a-b*c'

The as_string is just a wrapped ''.join call.

Just to name a few alternatives:

These are generalized solutions that work on an arbitary number of sequences and iterables. With only two iterables and if you don't want to use external packages using a zip or itertools.zip_longest approach (see other answers) is probably easier.

Upvotes: 0

宏杰李
宏杰李

Reputation: 12158

from itertools import zip_longest,chain
list1 = ['a','b','c']    
list2 = ['*','-']
''.join(i+j for i,j in zip_longest(list1, list2, fillvalue=''))

or:

list1 = ['a','b','c']    
list2 = ['*','-']
def item_gen(list1, list2):
    for i,j in zip(list1, list2):
        yield i
        yield j
    yield list1[-1]

each = item_gen(list1, list2)
''.join(each)

Upvotes: -3

derM
derM

Reputation: 13691

You might use the itertools Many posibilities, e.g.

list1 = ['a', 'b', 'c']
list2 = ['-', '*']
''.join(map(''.join, itertools.izip_longest(list1, list2, fillvalue='')))
''.join(itertools.chain(*itertools.izip_longest(list1, list2, fillvalue='')))

Upvotes: 2

ettanany
ettanany

Reputation: 19806

You can slice the first list to get a sublist with the same length as the second list, then apply zip() to the result. extend is used to add the other elements of the first list:

list1 = ['a','b','c']
list2 = ['-','-']

my_list = [''.join(item) for item in zip(list1[:len(list2)], list2)]
my_list.extend(list1[len(list2):])
str_out = ''.join(my_list)
print(str_out)
# Output: 'a-b-c'

Upvotes: 0

Rahul K P
Rahul K P

Reputation: 16081

Try this,

In [32]: ''.join(i+j for i,j in zip(list1,list2+['']))
Out[32]: 'a-b-c'

Just add a black ('') element at end of list2. Then just apply zip and join.

Tried with another example,

In [36]: list2 = ['*','-']
In [37]: ''.join(i+j for i,j in zip(list1,list2+['']))
Out[37]: 'a*b-c'

Upvotes: 1

Billy
Billy

Reputation: 5609

Borrowing from this answer regarding interleaving lists:

''.join(val for pair in zip(list1, list2) for val in pair) + list1[-1]

Upvotes: 0

Jalo
Jalo

Reputation: 1129

You can use NumPy arrays, as their indexing tools are very useful for the purpose of the OP:

list1 = np.array(['a','b','c'])
list2 = np.array(['*','-'])
final_list = np.zeros(len(l1) + len(l2)).astype('S1')
list3[0::2] = list1
list3[1::2] = list2

result_string = ''.join(list3)

The result will be:

'a*b-c'

Upvotes: 0

Maroun
Maroun

Reputation: 95948

Assuming your lists always correct, you can do:

list1 = ['a','b','c']
list2 = ['-','-']

res = []
for i1, i2 in zip(list1, list2):
    res.append(i1)
    res.append(i2)

res.append(list1[-1])

print ''.join(res)

Iterate on the two lists simultaneously, and add an item from list1 and then from list2. When the loop terminates, you have one more item in list1, which you append manually.

Another solution would be having a separate counter for each list:

list1 = ['a','b','c']
list2 = ['-','-']

res = []
j = 0
for i1 in list1:
    res.append(i1)
    if j < len(list2):
        res.append(list2[j])
        j += 1

print ''.join(res)

Upvotes: 0

Related Questions