2017-02-23 5 views
1

プロジェクトの目的: 入力を既存のインデックスと比較し、用語または文字の頻度で最も近い一致を返します。 基本的に所望の出力は、このような指標で比較関数で行います:2つのネストされたディクショナリ内のキーが一致するかどうかを調べる方法は?

index = {'nino': {'n': '0.50', 'o': '0.25', 'i': '0.25'}, 
     'pablo': {'l': '0.20', 'p': '0.20', 'o': '0.20', 'b': '0.20', 'a': '0.20'}} 

と私は同様の出力、文字を返すためにも手紙の周波数を計算することになるから、入力文字列と比較周波数:

{'y': '0.20', 'k': '0.20', 'o': '0.20', 'c': '0.20', 'r': '0.20'} 

これを取得したら、両方の辞書を繰り返して、どの文字が存在するかをチェックします。 それらが存在すると、単語と属性ポイントの頻度を比較して、結果を比較し、ほとんどの点を評価するものを返します。 私はコードの最後に問題はありませんでした。 しかし、私が正しいとは思えないのは、2つの辞書とそのネストされた要素の間の反復です(値は辞書です。 2組のアプローチを試してから、両方のセットの結合を取得しました。次の部分にできない:それはセットが不変であることを述べている

その後、私は私がここで見つけるの答えからコードを適応しようとしました:。

if all(string_index[k] == v for k, v in index.items() if k in index): 

python dictionary match key values in two dictionaries をそれから私は上記の回答からインスピレーションを得た、このオプションを試してみましたしかし、その後私はキーエラー、岩(最初のキー)、それはどこかにiteraではないことがわかります私が比較したいと思っているものを比較します。

そこには反復部分にこだわっています。 私がそれを正しくすると、私はそれを終えることができることを知っています。 ヒントやヒントありがとう!

index={} 
#Get frequency of a letter 

def frequency_return(string,letter): 
    count=0 

    for letters in string: 
     if letters==letter: 
      count+=1 
    return count 

#Scan all letters: if a letter has not been searched then count 
def get_frequency(string): 
    range_string=string 
    length_string=len(string) 
    datastore={} 
    target=0 
    frequency=0 
    while len(range_string)!=0: 
      # datastore.append(range_string[target]) 
      frequency = (int(frequency_return(range_string,range_string[target]))/length_string) 
      frequency = format(frequency, '.2f') 
      datastore.update({range_string[target]:frequency}) 
      range_string = range_string.replace(range_string[target],'') 
    return datastore   

def index_string(string): 

    if string not in index: 

     index.update({string: (get_frequency(string))}) 
    return index 

index_string("pablo") 
index_string("rocky") 
index_string("rigo") 
index_string("nino") 

print (index) 

############################################################################################### 


def comparator (string, index): 
    string_index=get_frequency(string) 
    result={} 
    if all(string_index[k] == v for k, v in index.items() if k in index): 
    result.update(string_index) 
    return result 

print(comparator("baobab", index)) 
+0

あなたの問題を完全に理解することなく、あなたは 'collections'から' defaultdict'を考えましたか?これまで知られていないキーを参照すると、defaultdictは、標準のdictのように 'KeyError'を発生させるのではなく、デフォルト値で作成します。 – nigel222

+0

同様の考え方は、 'get'メソッドを使って標準ディレクトリにアクセスすることです。 'd '(' key'、 'default') '' key ''に 'd 'の項目がなければ' default'を返します。そのようなエントリがある場合、値一致キーを返します。 – nigel222

+0

希望する出力は何ですか? – asongtoruin

答えて

1

あなたの希望する出力が何であるかはっきりしませんが、私はそれを整理しています。すべての

まず、我々は単にCounterを使用して、各単語の文字の比率のあなたの計算を整理することができます

from collections import Counter 


def get_proportions(word): 
    frequencies = dict(Counter(word)) 
    for letter, value in frequencies.items(): 
     frequencies[letter] = float(value)/len(word) 
    return frequencies 

AはCounterそれが単語内の各文字を見つけた回数を返します。これを比率にするために、各値を単に単語の長さで割ります。私たちがしなければ使用でこれを実証するために、:

comparison_dict = {} 
for word in ['pablo', 'rocky', 'rigo', 'nino']: 
    comparison_dict[word] = get_proportions(word) 

print(comparison_dict) 

を私たちは、プリントアウト:

{'rigo': {'i': 0.25, 'r': 0.25, 'g': 0.25, 'o': 0.25}, 'rocky': {'y': 0.2, 'c': 0.2, 'r': 0.2, 'k': 0.2, 'o': 0.2}, 'nino': {'i': 0.25, 'o': 0.25, 'n': 0.5}, 'pablo': {'a': 0.2, 'p': 0.2, 'b': 0.2, 'l': 0.2, 'o': 0.2}} 

私は仮定あなたのコードの最後の部分が提供間の「距離」のいくつかの種類をうまくすることを目指しています単語と比較辞書の各単語?我々は(計算、与えられた単語辞書単語の各文字について

def compare_to_dict(word, compare_to): 
    props = get_proportions(word) 
    comparison_scores = [] 
    for key in compare_to.keys(): 
     word_distance = sum(abs(props.get(letter, 0) - compare_to[key].get(letter, 0)) 
          for letter in set(word + key)) 
     comparison_scores.append((key, word_distance)) 
    return sorted(comparison_scores, key=lambda x: x[1]) 

:私はあなたが以下の機能を提供します与えられた単語の文字値と辞書の単語の文字の値の間の差の合計を、したいと仮定しましたつまり、与えられた単語が'baobab'であり、辞書の単語が'rigo'ならば、rは0.25(0.25-0)に寄与し、一方oは0.083333(0.25-0.0166666)に寄与する。私たちはこれらの差異の合計に基づいてこれをソートします。返されるリストの最初のエントリは、辞書内の指定された単語の「最も近い」単語です。例えば

、もし我々print(compare_to_dict('baobab', comparison_dict))我々が得る:

[('pablo', 0.8666666666666666), ('rigo', 1.6666666666666665), ('rocky', 1.6666666666666665), ('nino', 1.6666666666666665)] 

'pablo''baobab'に最も近い単語であることを示唆しています。

これがまさにあなたの後ろにあるのかどうか分からないので、そうでない場合は教えてください。完全なコードは次のとおりです:

from collections import Counter 


def get_proportions(word): 
    frequencies = dict(Counter(word)) 
    for letter, value in frequencies.items(): 
     frequencies[letter] = float(value)/len(word) 
    return frequencies 


def compare_to_dict(word, compare_to): 
    props = get_proportions(word) 
    comparison_scores = [] 
    for key in compare_to.keys(): 
     word_distance = sum(abs(props.get(letter, 0) - compare_to[key].get(letter, 0)) 
          for letter in set(word + key)) 
     comparison_scores.append((key, word_distance)) 
    return sorted(comparison_scores, key=lambda x: x[1]) 


comparison_dict = {} 
for word in ['pablo', 'rocky', 'rigo', 'nino']: 
    comparison_dict[word] = get_proportions(word) 

print(comparison_dict) 

print(compare_to_dict('baobab', comparison_dict)) 
+0

これはまさに私が探していたものです。私はカウンターライブラリーを詳しく見ていきます。実際、あなたのソリューションは私が心に留めていたよりも優れたシステムを使います。ありがとう!私はこのような図書館をもっと見るだろう –

+0

@Thomasmeriauxはそれを聞いてうれしい。物事を最初から構築する方法を理解することは良いことですが、Pythonのショートカットは物事を合理化することができます。これで問題が解決した場合は、左側の緑色のチェックマークを使用して回答としてマークすると、他の人に検索されやすくなります。 – asongtoruin

2

あなたはあなたが反復していることを誤解していると思います。あなたは、ある一つの理由でKeyError例外例外を持っている - この行に:forループで

if all(string_index[k] == v for k, v in index.items() if k in index): 

を、あなたは「RIGO」または「パブロ」辞書のキーを反復処理していません。代わりに、あなたは辞書を反復処理している、それはキーがありますなど、{'i': '0.25', 'r': '0.25', 'g': '0.25', 'o': '0.25'}'rigo', 'nino', 'rocky', 'pablo'を(これはそのコードでkは)と{'a': '0.20', 'p': '0.20', 'b': '0.20', 'l': '0.20', 'o': '0.20'}

あなたはこの小さなスニペットでそれを試すことができます。

>>> for k,v in index.items(): 
...  print("key is:{}, value is:{}".format(k,v)) 
... 
"key is:pablo, value is:{'a': '0.20', 'p': '0.20', 'b': '0.20', 'l': '0.20', 'o': '0.20'}" 
"key is:rigo, value is:{'i': '0.25', 'r': '0.25', 'g': '0.25', 'o': '0.25'}" 
"key is:nino, value is:{'i': '0.25', 'o': '0.25', 'n': '0.50'}" 
"key is:rocky, value is:{'y': '0.20', 'c': '0.20', 'r': '0.20', 'k': '0.20', 'o': '0.20'}" 

さらに、index.items()を反復しているかのように、これはあまり意味がありません.kは常にインデックスにあります。

最後に、kは値 'RIGO' の一つ、 '岩場'、 'パブロ'、 'ニノ'、この部分であるとして:

string_index[k] == v 

...キーにstring_indexを評価しようとしています " string_index.keys()の要素ではない「rigo」のように、プログラムは例外を返します。

推奨されているように、コードを書き直したり、コレクションからより良いデータ構造を使用したりしてください。

関連する問題