2

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 = ['*','-']

Kir Chou
  • 2,980
  • 1
  • 36
  • 48
ThatQuantDude
  • 759
  • 1
  • 9
  • 26

9 Answers9

2

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='')))
1

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)
Gennady Kandaurov
  • 1,914
  • 1
  • 15
  • 19
1

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'
Rahul K P
  • 15,740
  • 4
  • 35
  • 52
0

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)
Maroun
  • 94,125
  • 30
  • 188
  • 241
0

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'
Jalo
  • 1,131
  • 1
  • 12
  • 28
0

Borrowing from this answer regarding interleaving lists:

''.join(val for pair in zip(list1, list2) for val in pair) + list1[-1]
Community
  • 1
  • 1
Billy
  • 5,179
  • 2
  • 27
  • 53
0

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'
ettanany
  • 19,038
  • 9
  • 47
  • 63
0

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.

MSeifert
  • 145,886
  • 38
  • 333
  • 352
-3
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)
宏杰李
  • 11,820
  • 2
  • 28
  • 35