2016-03-04 61 views
1

我正在試圖創建一個函數,當給定字符串時,將刪除重複字符的第一次發生。但是有一個細節讓我意識到:不連續的字符不是重複的。因此,'bookkeeper'將是'bokeper',但我的功能吐出了'bokepr'。我怎樣才能解決這個問題?這是我的功能。使用列表刪除重複字符的第一次發生

def remove_repeat(message): 
    placeholder = [] #The spot that our answer will be built up in 
    seen_chars = [] #The place that will hold our seen characters 
    for c in message: 
     if c not in seen_chars: 
      seen_chars.append(c) 
     if c not in placeholder: 
      placeholder.append(c) 
    result = "" 
    for c in placeholder: 
     result = result + c 
    return result 
+0

從字符列表中創建一個字符串應該用'''.join()' – Kupiakos

+0

來完成你的代碼不會刪除第一個字符,而是除第一個字符外所有的事件,所以我是有點困惑你實際上想要達到的目標。 「eetee」和「eeettteee」的預期結果是什麼? –

+0

連續三個字符會發生什麼?例如,「boooo」應該變成「booo」還是「bo」? – timgeb

回答

1
def remove_repeat(message): 
    result = [] 
    curr = None 
    for c in message: 
     if c != curr: 
      curr = c 
      result.append(c) 

    return "".join(result) 
2

可以使用itertools.groupby()僅由單個發生,替換字符的所有連續運行(這似乎是你正在嘗試做的):

>>> "".join(k for k, it in itertools.groupby("bookkeeper")) 
'bokeper' 
0

這種算法是類似到Dyno Fu的,但不是使用變量來存儲前一個字符,而是使用zip函數將兩個字符串數據副本並行迭代,並偏移一個位置。爲了創建偏移量數據,我們將字符串的一個副本轉換爲&前面的None,因爲我們不能將None對象放入字符串中。

def remove_repeat(msg): 
    return ''.join([d for c, d in zip([None] + list(msg), msg) if d != c]) 

print(remove_repeat('bookkeeper'))  

輸出

bokeper 

使用列表理解構建一個字符串,然後使用.join將結果轉換成字符串是Python中的相當標準的成語,因爲它比重複字符串連接更有效。現代版本的Python對小字符串進行了優化字符串連接,但您會看到與長度超過100個字符的字符串顯着差異。

0

我想用正則表達式添加另一個解決方案。 「booo」之類的東西是否應該成爲「bo」(刪除除重複之外的所有東西)或「boo」(刪除一個副本)都有點不清楚。所以這裏有兩種解決方案:

刪除一個重複:

>>> import re 
>>> s = 'bookkeeperrrr' 
>>> re.sub(r'(.)(\1+)', r'\2', s) 
'bokeperrr' 

我們正在尋找這是重複至少兩次任意字符,然後替換爲匹配模式與匹配減去重複的人物之一。

刪除所有,但一個重複:

>>> re.sub(r'(.)(\1+)', r'\1', s) 
'bokeper' 

相同的邏輯在這裏,但我們與複製的字符只是一個替補。

如果「任何字符」過於籠統,則將正則表達式中的點替換爲您喜歡的任何字符類,例如[a-zA-Z]