2017-04-06 40 views
6

所以,我有這個名單Python中加入列表中的元素以取巧的方法

l = ['abc', 'retro', '', '', 'images', 'cool', '', 'end'] 

和,我想加入他們的方式,如:

l = ['abc retro', '', '', 'images cool', '', 'end'] 

我試過很多方法,但似乎沒有任何工作。有什麼建議麼?

+0

因此,空字符串不應該被加入? –

+1

你想要列表中的空字符串之間的元素? – Surajano

+0

是的,空的元素必須在那裏。 –

回答

6

您可以使用itertools.groupby和列表理解。將其分組爲'' s和非'',並使用str.join加入來自後者的項目。在修真的後部三元操作員使用組密鑰來決定如何對每個組做:

from itertools import groupby 

l = ['abc','retro','','','images','cool','','end'] 

r = [j for k, g in groupby(l, lambda x: x=='') 
          for j in (g if k else (' '.join(g),))] 
print(r) 
# ['abc retro', '', '', 'images cool', '', 'end'] 
+1

只是完美..! –

+0

您可以通過用'bool'替換lambda來簡化(並加速它),並在內部循環中反轉測試:'r = [j for k,g in groupby(l,bool)for j in([ ''.join(g)] if k else g)]'。 'bool'是在C中實現的,因此它應該比調用Python函數(lambda)更快。 –

1

使用itertools.chainitertools.groupby()bool的關鍵功能:

In [21]: from itertools import groupby, chain 

In [22]: list(chain.from_iterable([' '.join(g)] if k else g for k, g in groupby(lst, bool))) 
Out[22]: ['abc retro', '', '', 'images cool', '', 'end'] 
4

這裏的另一個版本使用良好的舊while while循環來編輯列表到位:

In [6]: l=['abc','retro','','','images','cool','','end'] 

In [7]: i = 1 
    ...: while i < len(l): 
    ...:  while l[i-1] and l[i]: 
    ...:   l[i-1] += ' ' + l[i] 
    ...:   del l[i] 
    ...:  i += 1 
    ...: 

In [8]: l 
Out[8]: ['abc retro', '', '', 'images cool', '', 'end'] 
+1

我會付出代價的,雖然突變源列表_may_不可取,但我想這裏沒問題,因爲OP將修改後的列表分配回'l'。 –

1

沒有使用lambda函數與列表理解喲你可以通過迭代列表來以舊式的方式做到這一點。

l=['abc','retro','','','images','cool','','end'] 

result = list() 
for x in range(len(l)): 
    if l[x]: 
     #Its not empty lets move to next until we find one or more consecutive non empty elements 
     for y in range(x+1, len(l)): 
      if l[y]: 
       result.append(l[x]+' '+l[y]) 
       x = y 

      else: 
       x = y 
       break 
    else: 
     result.append(l[x]) 

    #We are going to append last element, because we might have read an empty before 
    if x == len(l)-1: 
     result.append(l[x]) 

print result 

^^上面的解決方案是不正確的,並且將只適合這種情況下。

下面是一個使用協議棧的方法

l=['abc','retro','','','images','are','cool','','end'] 

result = list() 
previous = '' 
while l: 
    current = l.pop(0) 
    if current: 
     if previous: 
      previous+=' '+current 
     else: 
      previous = current 
    else: 
     result.append(previous) 
     result.append('') 
     previous = '' 

result.append(current) 
print result 
+0

如果一行中有兩個以上的單詞,例如'l = ['abc','retro','','','images','are','cool' ,'','end'],或者'l'以空字符串結尾。 –

+0

是的你是正確的,也忘了python中的迭代器。將更新文章與另一個解決方案 – Ilhicas

+0

新版本更好,但它仍然有一些問題。它增加了額外的空字符串,它不會正確處理列表的末尾。你可以通過將'result.append(previous)'改成'if previous:result.append(previous)',並用'if previous:result.append(previous)'替換'result.append(current)'來解決它。 。另外,'.pop(0)'是效率低下的,因爲所有後續列表項必須在刪除第一個列表項後被移動。 「用電流:l」好多了 –

1

這裏的另一個groupby方法的另一個通用的辦法。它不使用列表組件,但我認爲這使它更具可讀性。 ;)與其他(當前)答案不同,它使用單個循環而不是嵌套循環(除了內部使用的循環外)。

我們使用bool作爲關鍵函數,所以這些組是true-ish或false-ish。假ish組是一組空字符串,所以我們擴展輸出列表new與組。一個真正的組只包含非空字符串,所以我們加入它,並將結果追加到new

from itertools import groupby 

old = ['abc', 'retro', '', '', 'images', 'cool', '', 'end'] 

new = [] 
for k, g in groupby(old, key=bool): 
    if k: 
     new.append(' '.join(g)) 
    else: 
     new.extend(g) 

print(new) 

輸出

['abc retro', '', '', 'images cool', '', 'end'] 
相關問題