2016-03-31 9 views
0

文字列が与えられた場合、 "TATA__"とすると、その文字列の隣接文字間の差の合計数を見つける必要があります。すなわち、TとAとの間に差異があるが、AとA、または_と_との差異は存在しない。Python 3の文字列の文字数の差の数

私のコードは多かれ少なかれこれを私に伝えます。しかし、 "TTAA__"のような文字列が与えられた場合、それは計画どおりに動作しません。

文字列内の文字を取り、その隣の文字が最初の文字と等しくないかどうかを確認する必要があります。それが実際に等しくない場合、私は実行カウントに1を加える必要があります。等しい場合、何もカウントに追加されません。

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

私は応答として4を得るnum_diffs( "TATA__")を使用して、それを実行すると:私はこれまで持っているもの

これ。 num_diffs( "TTAA__")でそれを実行すると、私も4になります。答えは2でなければなりません。

それが意味をなさえすれば、誰かが私のエラーがどこにあるのかを教えてくれるでしょうか?私は状態[char2]と関係があると感じています。申し訳ありませんが、これがちょっとした問題のように思えるのは、私がPython言語に全く新しいことです。

+0

* char2 *は使用前に定義されていないため、あなたの例は[検証可能または完全ではありません](http://stackoverflow.com/help/mcve)です。コード例を修正してください。 –

+0

'char2'の値は何ですか? – ILostMySpoon

+0

しかし、私は 'num_diffs(" TTAA __ ")に' 3'を期待しています。なぜ '2'であるべきか説明できますか? – styvane

答えて

1

これを行う方法はいくつかあります。
最初に、インデックスを使用して文字列を繰り返し、各文字を前のインデックスの文字と比較できます。
第2に、前の文字を別の変数に記録することができます。 2番目はあなたの試みに近いと思われます。

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変数は関数の本体内で初期化されなかったということでしたので、でした関数の動作を予測することは不可能です。

しかし、インデックスで作業するのはPythonの方法ではありません。エラーが発生しやすくなります(私が作ったミスのコメントを参照)。あなたはそれが一度に文字列のペアを介して1つのループ、文字のペアをするような方法で機能を書き換えたいことがあります。

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

、非常にロジックがはるかに簡潔に書くことができること - を参照します@イルジャの答え。少しこれを開くには

+1

'range(1、len(state)-1)ではなく' range(1、len(state)) 'でなければなりません。 – khelwood

+0

@khelwoodそれは 'IndexError'を発生させます – Bolo

+0

いいえ、それはできません。文字列の最後の2文字を比較してコードが欠落しています。 – khelwood

2
import operator 

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

、それは第二の文字で始まるstatestate上、!=operator.neをマッピングします。 map関数は複数のiterableを引数として受け取り、iterablesの1つが使い果たされるまで(state[1:]が最初に停止するまで)、指定された関数の位置引数としてそれらの要素を1つずつ渡します。

mapの結果は反復可能なブール値になりますが、boolintから継承されるため、一部のコンテキストではそのように扱うことができます。ここでは、隣接する文字が異なる点を表すため、Trueの値に興味があります。そのマッピング上でsumを呼び出すことは、明らかに次のステップです。

文字列スライシングとは別に、すべてがpython3でイテレータを使用して実行されます。

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機能を調査する場合があります。一つはスライスの巨大な文字列を避けたい場合は、あまりにも文字列state上でイテレータを使用することが可能です。

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()機能が一緒に同じエントリをグループ化することによって動作します。 keygroupを返します。キーは一致する単一エントリであり、グループは一致するエントリのリストです。だからそれが戻ってくるたびに、違いがあるとあなたに伝えています。

+0

このコードはこれらの特定の例では機能しますが、私は複数のケースでうまくいくものを探していました。 「TATATA__」や「TAATATATAT__」などです。しかし、ありがとうございました! (私があなたのコードで言ったことをあなたが含んでいれば、私を許してください。私はこのPythonの事のすべてに本当に新しいです。) –