Is There A More Pythonic Way To Conditionally Merge Adjacent List Elements?
Solution 1:
Not sure if more pythonic, but certainly more concise.
"\0".join(myList).replace("\\\0","").split("\0")
If you can't make assumptions that the strings don't include \0
you can generate the separator:
import string
import random
sep = ""whileany(sep in s for s in myList):
sep += random.choice(string.ascii_uppercase + string.digits)
sep.join(myList).replace("\\"+sep,"").split(sep)
Solution 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
prints
['echo FooBar and some more foos', 'cat /etc/cpuinfo',
'cat /path/to/long/deep/directory/that/goes/on/forever']
Solution 3:
If this is pythonic for you:
reduce(lambda agg, x: (agg +
[agg.pop()[:-1] + x] if agg[-1].endswith('\\') else
agg + [x]) if len(agg) > 0 else
agg + [x], myList, [])
I think it's cool and useful to understand (even if not to use)
Explanation: uses the aggregated list in reduce
and looks back to the last element to append to it if needed. Otherwise appends to list. Doesn't look back on first element to avoid exception.
['echo FooBar and some more foos', 'cat /etc/cpuinfo', 'cat /path/to/long/deep/directory/that/goes/on/forever']
Solution 4:
A possibly easier to read solution is
wp = 0for L in myList:
if wp and myList[wp - 1].endswith('\\'):
myList[wp - 1] = myList[wp - 1][:-1] + L
else:
myList[wp] = L
wp += 1del myList[wp:]
For me this is easier to read because the wp
"write-pointer" pattern to modify arrays inplace is something that I've in the fingers. Readiility is in the eye of the beholder...
A purely functional solution (no assignments at all) could be
defmerge_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)
but it really doesn't belong to Python.
Another version could be written as a generator, accepting any iterable:
defmerge_continuations(it):
prefix = Nonefor L in it:
if prefix isNone:
prefix = L
elif prefix.endswith('\\'):
prefix = prefix[:-1] + L
else:
yield prefix
prefix = L
if prefix isnotNone:
yield prefix
not my preferred approach, but idiomatic in Python
Solution 5:
It may not be the shortest, but it's fairly readable and Pythonic.
out, grp = [], []
for s in my_list:
if s.endswith('\\'):
grp.append(s[:-1])
else:
out.append(''.join(grp) + s)
grp = []
print(out)
Post a Comment for "Is There A More Pythonic Way To Conditionally Merge Adjacent List Elements?"