2013-03-21 59 views
3

我有一個表示數據結構遍歷的字符串列表。我想將鏈接列表遍歷摺疊成更緊湊的表示形式。爲此,我想計算相鄰的nextprev鏈接的數量並將它們合併爲一個整數。將鏈接中的「下一個」和「前一個」鏈接拼合起來

這裏是我想要做的轉換的例子:

['modules']         --> ['modules'] 
['modules', 'next']       --> ['modules', 1] 
['modules', 'prev']       --> ['modules', -1] 
['modules', 'next', 'next', 'next', 'txt'] --> ['modules', 3, 'txt'] 
['modules', 'next', 'prev', 'next', 'txt'] --> ['modules', 1, 'txt'] 
['super_blocks', 'next', 's_inodes', 'next'] --> ['super_blocks', 1, 's_inodes', 1] 

每個next鏈接數爲+1,並且每個prev爲-1。相鄰next s和prev s彼此抵消。他們可以以任何順序來。

我有一個工作解決方案,但我努力尋找一個令人滿意的優雅和Pythonic解決方案。

回答

1

如何:

def convert(ls): 
    last = None 
    for x in ls: 
     if x == 'prev': x = -1 
     if x == 'next': x = +1 
     if isinstance(x, int) and isinstance(last, int): 
      x += last 
     elif last: # last is not None if you want zeroes 
      yield last 
     last = x 
    yield last 
6

你可以使用一個發電機:

def links(seq): 
    it = iter(seq) 
    while True: 
     el = next(it) 
     cnt = 0 
     try: 
      while el in ['prev', 'next']: 
       cnt += (1 if el == 'next' else -1) 
       el = next(it) 
     finally: 
      if cnt != 0: 
       yield cnt 
     yield el 

print list(links(['modules', 'next', 'prev', 'next', 'txt'])) 

值得注意的是包含nextprev同等數量的順序被完全刪除。如果這就是你想要的(我認爲這個需求有點不清楚),那麼將代碼更改爲0會很容易。

+0

[ '模塊', '下', '分組', 'TXT'] - > FAIL。 – unbeli 2013-03-21 22:08:30

+0

@unbeli:我認爲這是一個強大的。這個角落案件的要求不清楚。 – NPE 2013-03-21 22:09:39

+0

我認爲這很清楚,next/prev應該以整數形式出現。對於那種情況和你的代碼,他們不會。 – unbeli 2013-03-21 22:10:37

1

這是最簡單的想法。簡單直觀是理解,調試和未來維護的有價值的品質。

def process(l): 
    result = [] 
    count = 0 
    keepCount = False 
    for s in l: 
     if s == "next": 
      count += 1 
      keepCount = True 
     elif s == "prev": 
      count -= 1 
      keepCount = True 
     else: 
      if keepCount: 
       result.append(count) 
       count = 0 
       keepCount = False 
      result.append(s) 
     # end if 
    # end for 
    if keepCount: 
     result.append(count) 

    return result 
# end process() 

雖然我喜歡NPE更好地使用發電機。 (我可以很容易地通過將'result.append()'改爲'yield'來轉換)他的(original)答案與我的幾乎相同,但是如果下一個/ prev標記相同的數字相鄰。

1

怎麼樣一點點reduce()

def collapse(lst): 
    was_link = [False] # No nonlocal in Python 2.x :(
    def step(lst, item): 
     val = { 'prev': -1, 'next': 1 }.get(item) 

     if was_link[0] and val: 
      lst[-1] += val 
     else: 
      lst.append(val or item) 
     was_link[0] = bool(val) 

     return lst 

    return reduce(step, [[]] + lst) 
相關問題