2016-12-07 3 views
2

У меня есть два списка разных размеров, n и n-1. Я должен объединить два списка, которые выглядят как этотСоедините два списка разной длины между собой

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

Они должны быть объединены, чтобы получить s.th как этот

str_out = 'a-b-c' 

Я попытался выяснить, элегантный способ сделать это, но только удалось прийти к этому решению

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

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

print(string2) 

, который печатает

'a-b-c-' 

Ищу красивее реализацию или как я могу избавиться от окончательного тира (-)

EDIT: Для уточнения, списки будут динамичными и песни2 может содержать произвольные символы.

например: list2 = ['*','-']

+0

Будет ли один список всегда быть короче другого? И если да, то знаете ли вы? –

+0

yes, list2 всегда будет короче 1 – ThatQuantDude

+1

'. '.join (chain.from_iterable (zip_longest (list1, list2, fillvalue =' ')))' ('izip_longest' в Python2) –

ответ

1

Попробуйте следующее:

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

Update добавить izip_longest версию:

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

Если вы уже используете itertools, почему бы не 'izip_longest()'? – derM

+0

Да, здесь также можно использовать 'izip_longest': ' "" .join (x для x в цепочке (* izip_longest (list1, list2)), если x не является None) ' –

+1

У меня есть' TypeError: объект NoneType ' не является вызываемым' для первого решения в Python 3, поэтому это решение Python 2. –

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

или:

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) 
+0

спасибо за ваш ответ, если только что обновили мой вопрос, присоединяйтесь не к сожалению – ThatQuantDude

0

Предполагая, что ваши списки всегда правильно, вы можете сделать:

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) 

итерацию по спискам одновременно, и добавить вещь от list1, а затем от list2. Когда цикл завершается, у вас есть еще один элемент в list1, который вы добавляете вручную.

Другим решением было бы наличие отдельного счетчика для каждого списка:

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

Попробуйте это,

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

Просто добавьте черный ('') элемент в конце list2. Затем просто примените zip и join.

Попробовал с другим примером,

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

Вы можете использовать Numpy массивы, поскольку их индексирование инструменты очень полезны для целей ОП:

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) 

Результат будет:

'a*b-c' 
2

Вы можете использовать itertools Многие возможности, например.

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

заимствование из this answer относительно списков перемежения:

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

Вы можете нарезать первый список, чтобы получить подсписок с такой же длины, как и во втором списке, а затем применить zip() к результату. extend используется для добавления других элементов первого списка:

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' 
0

Есть несколько внешних пакетов, которые встроенные функции для такого рода «чередования» из итерируемых, просто чтобы показать одну из них: iteration_utilities.roundrobin (примечания, что я являюсь автором этой библиотеки):

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

as_string просто обернуты ''.join вызов.

Просто назвать несколько альтернатив:

Эти обобщенные решения, которые работают на произвольном количестве последовательностей и итерируемыми. Имея только два итератора, и если вы не хотите использовать внешние пакеты с использованием подхода zip или itertools.zip_longest (см. Другие ответы), вероятно, проще.

Смежные вопросы