2016-03-27 15 views
0

と複数の要素の類似度を算出私はすべての2番目の要素は、様々な長さを有する、ネストされたリストを持っている:ネストされたリストの不等長

lst = [[a,bcbcbcbcbc],[e,bbccbbccb],[i,ccbbccbb],[o,cbbccbb]] 

私の出力は、この表情でデータフレームのCSVである:

comparison  similarity_score 
    a:e   *some score  
    a:i   *some score 
    a:o   *some score 
    e:i   *some score 
    e:o   *some score 
    i:o   *some score 

私のコード:

similarity = [] 
for i in lst: 
    name = i[0] 
    string = i[1] 
    score = 0.0 
    length =(len(string)) 
    for i in range(length): 
     if string[i]==string[i+1]: 
      score += 1.0 
    new_score = (100.0*score)/length 
    name_seq = name[i] + ':' + name[i+1] 
    similarity.append(name_seq,new_score) 

similarity.pdDataFrame(similarity, columns = ['comparison' , 'similarity_score']) 
similarity.to_csv('similarity_score.csv') 

が、私はエラーが供給しています:

if codes[i]==codes[i+1]: 
      IndexError: string index out of range 

ありがとう! Pythonのドキュメントrangeによる

+0

numplacesは初期化されていますか? string [i] == string [i + 1]を意味する場合を除いて、コード[i] == codes [i + 1]はコードスニペットには表示されません。 – elhefe

+0

numPlacesとは(たぶん 'length ')?例外の行は、表示されたコードの行と一致しません。とにかく、別の時に2つの異なるものに同じ変数名を使用しているので、私はあなたが混乱していると思います。あなたのリストで 'name'が' a'であれば、あなたが 'name [i + 1]'している場所はまったく意味がありません。 – Blckknght

+0

@Blckknghtは訂正してくれてありがとう。私はforループの私とかなり混同していることを認めなければならない。 –

答えて

1

は一例で、次の処理を行います

あなたのコードで

>>>range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

(変数名に変更されていないと仮定して):つまり

... 
length =(len(string))   # For an input of 'bcb' length will be 3 
for i in range(length):   # For an input of 'bcb' range will be [0, 1, 2] 
    if string[i]==string[i+1]: # When i == 2 i + 1 == 3 which gives you the 
           # IndexError: string index out of range 
... 

を、入力bcbを与え、あなたのifステートメントは、次のインデックスを見ます:

(0,1)
(1,2)
(2,3)<--この場合3が問題です。 [0, len(string) - 1]

1

から、あなたの問題の反復処理を修正するには

私はあなたの最大の問題は、あなたが見たいようにトップレベルであなただけの、一度に一つのname,stringペアにname,string組のペアではなく反復処理しているということだと思いますあなたの出力に(ペアの名前a:eで示されているように)。

namestringの値を後でインデックスに追加しようとしていますが、そうすることで、2つの文字列を比較してスコアを計算します。同じ文字列。あなたが得ている例外は、i+1が文字列の最後から外れる可能性があるためです。内側ループのインデックスと外側ループ(name, stringペア)から取得されたアイテムの両方にiを使用しているので、さらに混乱が生じます。

組のペアを取得するために、私はitertools.combinationsを使用することをお勧め:

import itertools 

for [name1, string1], [name2, string2] in itertools.combinations(lst, 2): 

今、あなたはループの残りの部分に2名と2つの文字列変数を使用することができます。

私はあなたのスコアを得るために文字列を比較する方法を理解していません。なぜなら、それらは互いに同じ長さではないからです。文字列の最初の部分だけを比較し(長いものの末尾のビットを無視する)、zipを使用して、2つの文字列の間に対応する文字のペアを取得できます。その後、ジェネレータ式でそれらを比較し、bool結果(Trueは整数1Falseの特別なバージョンです)を合計して0のバージョンです。(あなたは長さの違いを不利にしたい場合は、おそらく大きな)あなたは、文字列の長さの小さい方で割ることができます。

common_letters = sum(c1 == c2 for c1, c2 in zip(string1, string2)) 
new_score = common_letters * 100/min(len(string1), len(string2)) 

次の2つの引数を持つappendを呼んでいるもう一つの明白な問題が、あります。実際に2タプルを追加する場合は、余分な括弧が必要です。

similarity.append((name_seq, new_score)) 
関連する問題