[英]Is there a more Pythonic way to conditionally merge adjacent list elements?
假設我有以下列表。
myList = ["echo FooBar \\", "and some more foos", "cat /etc/cpuinfo",
"cat /path/to/\\", "long/deep/directory/\\", "that/goes/on/forever"]
我想合並任何以\\
結尾的元素與右邊的元素,刪除過程中的\\
,並繼續這樣做,直到沒有更多元素帶尾隨\\
。
正確的輸出看起來像這樣。
['echo FooBar and some more foos',
'cat /etc/cpuinfo',
'cat /path/to/long/deep/directory/that/goes/on/forever']
這是我目前的解決方案,它是功能性的,但似乎比必要的復雜得多。
myList = ["echo FooBar \\", "and some more foos", "cat /etc/cpuinfo",
"cat /path/to/\\", "long/deep/directory/\\", "that/goes/on/forever"]
tmpItem = None
tmpList = []
for x in myList:
if tmpItem:
if tmpItem.endswith("\\"):
tmpItem = tmpItem[:-1] + x
else:
tmpList.append(tmpItem)
tmpItem = x
else: tmpItem = x
if tmpItem:
if tmpItem.endswith("\\"):
tmpList.append(tmpItem[:-1])
else:
tmpList.append(tmpItem)
print tmpList
有沒有更簡潔的方法在Python中執行此操作,可能使用更實用的習慣用法?
我看了一下reduce()
,但它似乎只讓你將一個減少從一個列表移動到一個元素,而不是另一個列表,但也許我低估了它的力量。
不確定是否更加pythonic,但肯定更簡潔。
"\0".join(myList).replace("\\\0","").split("\0")
如果您不能假設字符串不包含\\0
,則可以生成分隔符:
import string
import random
sep = ""
while any(sep in s for s in myList):
sep += random.choice(string.ascii_uppercase + string.digits)
sep.join(myList).replace("\\"+sep,"").split(sep)
myList = ["echo FooBar \\", "and some more foos", "cat /etc/cpuinfo",
"cat /path/to/\\", "long/deep/directory/\\", "that/goes/on/forever"]
ret = []
for i in myList:
if ret and ret[-1].endswith('\\'):
ret[-1] = ret[-1][:-1] + i
else:
ret.append(i)
print ret
版畫
['echo FooBar and some more foos', 'cat /etc/cpuinfo',
'cat /path/to/long/deep/directory/that/goes/on/forever']
如果這對你來說是pythonic:
reduce(lambda agg, x: (agg +
[agg.pop()[:-1] + x] if agg[-1].endswith('\\') else
agg + [x]) if len(agg) > 0 else
agg + [x], myList, [])
我覺得理解它很酷很有用(即使不使用)
說明:使用reduce
的聚合列表,並在需要時回溯到要附加到的最后一個元素。 否則附加到列表。 不回頭看第一個元素以避免異常。
['echo FooBar和一些更多的foos','cat / etc / cpuinfo','cat / path / to / long / deep / directory / that / go / on / forever']
一個可能更容易閱讀的解決方案是
wp = 0
for L in myList:
if wp and myList[wp - 1].endswith('\\'):
myList[wp - 1] = myList[wp - 1][:-1] + L
else:
myList[wp] = L
wp += 1
del myList[wp:]
對我來說這更容易閱讀,因為用於修改數組的wp
“寫指針”模式是我手指上的東西。 可讀性在旁觀者的眼中......
一個純功能的解決方案(根本沒有任務)可能
def merge_continuations(L, ix=0):
if ix >= len(L)-1:
return L
elif L[ix].endswith('\\'):
return merge_continuations(L[:ix] +
[L[ix][:-1] + L[ix+1]] +
L[ix+2:], ix)
else:
return merge_continuations(L, ix+1)
但它確實不屬於Python。
另一個版本可以寫成生成器,接受任何可迭代:
def merge_continuations(it):
prefix = None
for L in it:
if prefix is None:
prefix = L
elif prefix.endswith('\\'):
prefix = prefix[:-1] + L
else:
yield prefix
prefix = L
if prefix is not None:
yield prefix
不是我喜歡的方法,而是Python中的慣用法
它可能不是最短的,但它相當可讀和Pythonic。
out, grp = [], []
for s in my_list:
if s.endswith('\\'):
grp.append(s[:-1])
else:
out.append(''.join(grp) + s)
grp = []
print(out)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.