所以,我有這個名單Python中加入列表中的元素以取巧的方法
l = ['abc', 'retro', '', '', 'images', 'cool', '', 'end']
和,我想加入他們的方式,如:
l = ['abc retro', '', '', 'images cool', '', 'end']
我試過很多方法,但似乎沒有任何工作。有什麼建議麼?
所以,我有這個名單Python中加入列表中的元素以取巧的方法
l = ['abc', 'retro', '', '', 'images', 'cool', '', 'end']
和,我想加入他們的方式,如:
l = ['abc retro', '', '', 'images cool', '', 'end']
我試過很多方法,但似乎沒有任何工作。有什麼建議麼?
您可以使用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']
只是完美..! –
您可以通過用'bool'替換lambda來簡化(並加速它),並在內部循環中反轉測試:'r = [j for k,g in groupby(l,bool)for j in([ ''.join(g)] if k else g)]'。 'bool'是在C中實現的,因此它應該比調用Python函數(lambda)更快。 –
使用itertools.chain
和itertools.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']
這裏的另一個版本使用良好的舊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']
我會付出代價的,雖然突變源列表_may_不可取,但我想這裏沒問題,因爲OP將修改後的列表分配回'l'。 –
沒有使用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
如果一行中有兩個以上的單詞,例如'l = ['abc','retro','','','images','are','cool' ,'','end'],或者'l'以空字符串結尾。 –
是的你是正確的,也忘了python中的迭代器。將更新文章與另一個解決方案 – Ilhicas
新版本更好,但它仍然有一些問題。它增加了額外的空字符串,它不會正確處理列表的末尾。你可以通過將'result.append(previous)'改成'if previous:result.append(previous)',並用'if previous:result.append(previous)'替換'result.append(current)'來解決它。 。另外,'.pop(0)'是效率低下的,因爲所有後續列表項必須在刪除第一個列表項後被移動。 「用電流:l」好多了 –
這裏的另一個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']
因此,空字符串不應該被加入? –
你想要列表中的空字符串之間的元素? – Surajano
是的,空的元素必須在那裏。 –