Reputation: 833
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
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
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
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
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
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
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
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
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