所以最近我寫了這段代碼。這得到布爾值的列表,其包括如果所有False
值穿插n
島的True
值。事情是這樣的:擺脫循環
[False, False, False, True, True, False, False, False, True, True, True, False]
# [island 1] [ island 2 ]
現在我想這些分成n
列出每個島嶼都seaprated。對於上面的列表中,我將獲得:
[[False, False, False, True, True, False, False, False, False, False, False, False], #-> list has island 1
[False, False, False, False, False, False, False, False, True, True, True, False]] #-> list has island 2
這是我用來解決問題的方案:
import itertools as it
def getPosList(x):
segs = [ (s[0], list(s[1])) for s in it.groupby(x)]
allSegs = [ [] for s in segs if s[0] ]
i = 0
for s in segs:
s1, s2 = s
s2 = list(s2)
if s1:
for j, s in enumerate(allSegs):
if i == j: s += s2
else: s += len(s2)*[False]
i += 1
else:
for s in allSegs: s += s2
return allSegs
if __name__ == '__main__':
print getPosList([False, False, False, True, True, False, False, False, True, True, True, False])
這看起來很unPythonic與循環和虛擬變量。我覺得應該有比我剛纔寫的更優雅的解決方案。與dropwhile
,reduce
等有關。但是,我似乎無法拿出更好的東西。任何有關改進的建議?每當我看到這段醜陋的代碼時,我都會畏縮。
編輯:
我把靈感來自於feseje並用遞歸版本上來。
import itertools as it
def ppListTF(xs):
return '[' + '|'.join([ '#' if x else ' ' for x in xs ]) + ']'
def getPosList1(x):
'''
'''
if x == []: return []
curX = list(it.takewhile(lambda m: m == x[0] , x))
nextVals = getPosList1(list(it.dropwhile(lambda m: m == x[0], x)))
curX1 = [False]*len(curX)
if nextVals:
curX2 = [False]*len(nextVals[0])
if x[0]:
# The first element is True. Split the list here
if nextVals: return [curX+curX2] + [ curX1+j for j in nextVals]
else: return [curX] + [curX1]
else:
# Just add the series of False to whatever is returned
if nextVals: return [ curX+j for j in nextVals]
else: return [curX]
if __name__ == '__main__':
inp = [False, False, False, True, True, False, False, False, True, True, True, False, True, True, False, False, False, False]
val = getPosList1(inp)
if any(inp):
val = filter(any, val)
print 'i', ppListTF(inp)
for i, v in enumerate(val):
print i, ppListTF(v)
我還是喜歡Hrabals的回答。這是最好的。感謝所有發佈答案的人。
這個問題是更適合於[代碼審查(https://codereview.stackexchange.com/ )。 – grc 2014-10-02 08:23:01