簡體   English   中英

如何查找兩個嵌套字典中的鍵是否匹配?

[英]How to find if the keys within two nested dictionaries match?

項目目標:將輸入與預先存在的索引進行比較,並以術語或字母頻率返回最接近的匹配。 基本上所需的輸出將在比較函數中使用如下索引:

 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'}

有了這個,我會遍歷兩個詞典並檢查每個項目的字母。 一旦它們存在,我將比較單詞和屬性點中的頻率,然后比較結果並返回得分最多的那個。 我對代碼的結尾沒有任何麻煩。 然而,我似乎無法正確的是兩個字典和它們的嵌套元素之間的迭代(畢竟值是一個字典:我已經嘗試了兩個集合方法然后獲得兩個集合的聯合但是我無法下一部分:它說集合是不可變的。

然后我嘗試從我在這里找到的答案調整代碼: python字典匹配兩個字典中的鍵值然后我嘗試了這個選項靈感來自上面的答案:

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

但后來我得到了一個關鍵錯誤,搖滾(第一個鍵),它告訴我某個地方沒有迭代並比較我想要比較的東西。

在那里,我陷入了迭代部分。 一旦我做對了,我知道我可以完成它。 非常感謝任何暗示或提示!

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))

我認為你誤導了你正在迭代的東西。 由於某種原因,你有KeyError異常 - 在這一行:

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

在for循環中,您不會迭代'rigo'或'pablo'字典的鍵。 相反,你在字典上迭代,它有鍵: 'rigo', 'nino', 'rocky', 'pablo' (這是代碼中的k)和值{'a': '0.20', 'p': '0.20', 'b': '0.20', 'l': '0.20', 'o': '0.20'}{'i': '0.25', 'r': '0.25', 'g': '0.25', 'o': '0.25'}

你可以試試這個小片段:

>>> 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','rocky','pablo','nino'之一,這部分:

string_index[k] == v

...正在嘗試評估關鍵字'rigo'上的string_index,它不是string_index.keys()的元素,因此程序返回Exception。

如建議的那樣,嘗試重新編寫代碼或從集合中使用更好的數據結構。

目前還不太清楚你想要的輸出是什么,但我已經去了解它。

首先,我們可以通過簡單地使用一個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

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))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM