2016-03-31 69 views
0

給定一個字符串,可以說「TATA__」,我需要找出該字符串中相鄰字符之間的差異總數。即T和A之間存在差異,但A和A之間不存在差異,或_和_。Python 3中字符串中字符之間差異的數量3

我的代碼或多或少告訴我這一點。但是,當給出諸如「TTAA__」的字符串時,它不能按計劃工作。

我需要在該字符串中帶一個字符,並檢查它旁邊的字符是否與第一個字符不相等。如果確實不相等,我需要在運行計數中加1。如果相等,則不會在計數中添加任何內容。

這是我到目前爲止有:

def num_diffs(state): 
    count = 0    
    for char in state: 
     if char != state[char2]: 
      count += 1 
    char2 += 1 
    return count 

當我使用num_diffs( 「TATA__」)運行它,我得到4作爲響應。當我用num_diffs(「TTAA__」)運行它時,我也得到4.而答案應該是2.

如果任何有意義的,任何人都可以幫助修復它/指出我的錯誤在哪裏?我有一種感覺是與狀態[char2]有關。對不起,如果這看起來像一個微不足道的問題,那只是我對Python語言完全陌生。

+0

您的示例不是[可驗證或完整](http://stackoverflow.com/help/mcve),因爲* char2 *在使用前未定義。請修復您的代碼示例。 –

+0

'char2'的價值是什麼? – ILostMySpoon

+0

但我希望''3''num_diffs(「TTAA __」)'你能解釋爲什麼它應該是'2'嗎? – styvane

回答

1

有幾種方法可以做到這一點。
首先,您可以使用索引遍歷字符串,並將每個字符與前一個索引處的字符進行比較。
其次,你可以跟蹤一個單獨的變量中的前一個字符。第二個似乎更接近你的嘗試。

def num_diffs(s): 
    count = 0 
    prev = None 
    for ch in s: 
     if prev is not None and prev!=ch: 
      count += 1 
     prev = ch 
    return count 

prev是上一次循環迭代中的字符。在每次迭代結束時將其分配給ch(當前字符),以便下一次可用。

-1

努力使盡可能少的修改原來的代碼可能:

def num_diffs(state): 
    count = 0    
    for char2 in range(1, len(state)): 
     if state[char2 - 1] != state[char2]: 
      count += 1  
    return count      

一個與你原來代碼中的問題是,char2變量沒有在函數體內初始化,所以這是不可能預測函數的行爲。

但是,使用索引並不是Pythonic最常用的方式,而且容易出錯(請參閱有關我犯的錯誤的註釋)。您可能需要重寫功能,以這樣一種方式,它確實一個循環在一對字符串,同時一對字符:

def num_diffs(state): 
    count = 0 
    for char1, char2 in zip(state[:-1], state[1:]): 
     if char1 != char2: 
      count += 1 
    return count 

最後,非常邏輯可以更簡潔地寫 - 看看@ Ilja的回答。

+1

應該是'range(1,len(state))',而不是'range(1,len(state)-1)'。 – khelwood

+0

@khelwood會引發'IndexError' – Bolo

+0

不會。比較字符串中的最後兩個字符時,您的代碼缺失。 – khelwood

2
import operator 

def num_diffs(state): 
    return sum(map(operator.ne, state, state[1:])) 

要打開這個了一下,它映射!=operator.ne,在statestate在第2個字符開始。 map函數接受多個可迭代項作爲參數,並將來自這些元素的元素作爲位置參數逐一傳遞給給定函數,直到其中一個迭代項耗盡(在這種情況下,state[1:]將首先停止)。

map產生一個可迭代的布爾值,但由於python中的bool繼承自int,因此您可以在某些情況下對其進行處理。這裏我們對True值感興趣,因爲它們表示相鄰字符不同的點。通過映射調用sum是明顯的下一步。

除了字符串切片,整個事情運行在python3中使用迭代器。有可能在字符串state使用迭代器也一樣,如果一個人想避免切片巨大的字符串:

import operator 
from itertools import islice 

def num_diffs(state): 
    return sum(map(operator.ne, 
        state, 
        islice(state, 1, len(state)))) 
+0

非常感謝你Ilja!儘管導入並不完全符合我的想法,但它仍然是一個很好的解決方案。 –

1

您可能需要調查Python的groupby功能與這種分析的幫助。

from itertools import groupby 

def num_diffs(seq): 
    return len(list(groupby(seq))) - 1 

for test in ["TATA__", "TTAA__"]: 
    print(test, num_diffs(test)) 

這將顯示:

TATA__ 4 
TTAA__ 2 

groupby()函數工作通過分組相同的條目一起。它返回一個key和一個group,關鍵是匹配的單個條目,而該組是匹配條目的列表。所以每次它回來,它都會告訴你有一個區別。

+0

儘管這些代碼適用於這些特定的示例,但我一直在尋找可以在多種情況下工作的東西。如「TATATA__」或「TAATATATAT__」。儘管如此,非常感謝! (如果你在代碼中包含了我剛纔所說的內容,請原諒我,對於整個Python來說,我真的很陌生。) –