假设我有以下列表。
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()
,但似乎只允许你将一个减少从一个列表移动到一个元素,而不是另一个列表,但也许我低估了它的力量。
答案 0 :(得分:3)
不确定是否有更多的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)
答案 1 :(得分:2)
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']
答案 2 :(得分:1)
如果这对你来说是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
中的聚合列表,并在需要时回溯到要追加的最后一个元素。否则附加到列表。不回头看第一个元素以避免异常。
['回显FooBar和更多的foos',' cat / etc / cpuinfo',' cat / path / to / long / deep / directory / that / goes /上/永远']
答案 3 :(得分:0)
可能更容易阅读的解决方案是
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中的惯用法
答案 4 :(得分:0)
它可能不是最短的,但它具有相当的可读性和Pythonic。
out, grp = [], []
for s in my_list:
if s.endswith('\\'):
grp.append(s[:-1])
else:
out.append(''.join(grp) + s)
grp = []
print(out)