2015-12-07 53 views
0

增量值我在python數據字典:搜索的Python解釋並在發現

[ 
    {u'PhoneOwner': u'Bob', u'Frequency': 0, u'PhoneNumber': u'123456789'}, 
    {u'PhoneOwner': u'Sarah', u'Frequency': 0, u'PhoneNumber': u'98765431'} 
    ] 

我使用******中國的呼叫列表,我想嘗試和名單與字典和更新當從我的列表中的號碼在字典中,頻率最終前往:

[ 
    {u'PhoneOwner': u'Bob', u'Frequency': 5, u'PhoneNumber': u'123456789'}, 
    {u'PhoneOwner': u'Sarah', u'Frequency': 8, u'PhoneNumber': u'98765431'} 
    ] 

目前我有:

 with open("CallLog.txt") as connectedNumbers:   
     for line in connectedNumbers: 
     try: 
       phoneNumberDictionary[PhoneNumber] += phoneNumberDictionary[Frequency]1 
     except KeyError: 
       phoneNumberDictionary[PhoneNumber] = phoneNumberDictionary[Frequency]1 

我無法找到如何搜索字典的一個字段,如果找到匹配更新其他任何細節。 我哪裏錯了?

+0

您的輸入不是一本字典,而是一個字典列表。 – DainDwarf

+0

問題是,你沒有字典;你有一個列表的字典。沒有辦法通過電話號碼爲phoneNumberDictionary編制索引,而無需每次迭代都找到正確的字典。 –

+0

如果你想索引的電話號碼字典,你需要:'{123456789:(u'Bob」,0),......}'或'{123456789:{ '所有者': '鮑勃', '頻率': 0},...}' – DainDwarf

回答

2

無法搜索字典的價值:它是由它的鍵索引,和值不是在所有索引(事實上,他們甚至可能不會哈希的)。

然後你有兩種選擇:

  1. 重新擬訂您的問題,這樣的電話號碼居然是關鍵:

    { 
        u'123456789': {u'PhoneOwner': u'Bob', u'Frequency': 0}, 
        u'98765431': {u'PhoneOwner': u'Sarah', u'Frequency': 0}, 
    } 
    

    這是因爲它立刻讓你索引你的字典相當實用:

    with open("Calllog.txt") as log: 
        for line in log: 
         phoneNumberDictionary[line]['Frequency'] += 1 
    

    但它意味着你將不得不重做你的數據,可能很重,一個nd這可能不是最方便的,無論你想對數據做什麼(例如按所有者名稱搜索)

  2. 讓您的數據結構列表,並通過它直接搜索匹配:

    with open("Calllog.txt") as log: 
        for line in log: 
         entries = filter(lambda entry: entry['PhoneNumber'] == line, phoneNumberDirectory) 
         for entry in entries: 
          entry['Frequency'] += 1 
    

    這將做工精美(讓我們有幾個人有同一個電話號碼好,不好?這取決於你自己決定),但是當你每次走完你的整個目錄時,這顯然是非常無效的。如果你有一個已知的小數據集,這可能是最好的解決方案。

  3. (在我看來,最好的選擇),兩者的某種組合。通常,您可以存儲你的數據在一個對象中,有多個指標辭書:

    class PhoneNumbers(object): 
        def __init__(self, entries): 
         self.frequencies = [] 
         self.names = {} 
         self.numbers = {} 
         for i, entry in enumerate(entries): 
          self.frequencies.append(entry['Frequency']) 
          self.names[entry['PhoneOwner']] = entry['PhoneNumber'] 
          self.numbers[entry['PhoneNumber']] = i 
    
        def register_call(self, number): 
         self.frequencies[self.numbers[number]] += 1 
    
    data = PhoneNumbers(phoneNumberDictionary) 
    with open("Calllog.txt") as log: 
        for line in log: 
         data.register_call(line) 
    

    或圍繞這些線相匹配你打算用你的數據做一些變化。

+0

所以我已經能夠重新格式化數據,而是試圖增加頻率拋出了錯誤:phoneNumberDictionary [18667209918] [「頻率」] + = 1 類型錯誤:字符串索引必須是整數 –

+0

很難說得清這來自從沒有看到你的數據exacly,但它看起來像'phoneNumberDictionary [18667209918]'是一個字符串;你有沒有確定你用字典正確地初始化了你的字典條目? – val

+0

我能弄明白,我的語法是不正確的這是造成錯誤。 –

0

如果不是太晚改變你的數據結構,這將是更有效,從類型的字典列表改變爲與使用手機號碼作爲重點頂級字典類型的字典詞典。如果您使用的是列表,因爲順序很重要,你可以使用一個OrderedDict

要回答使用您當前的數據結構,你的問題:因爲你有一個字典列表,你需要做的第一件事就是找到對應於要增加電話號碼的字典。你可以使用一個功能類似下面index_dict_in_list()做到這一點:

def index_dict_in_list(list_, key, value): 
    """ 
    Given a list of dicts, a key, and a value, return the 
    index of the dict with the matching key:value pair. 
    """ 
    for idx, dict_ in enumerate(list_): 
     if dict_[key] == value: 
      return idx 
    return -1 

然後,你可以使用這樣的:

phonebook = [ 
    {u'PhoneOwner': u'Bob', u'Frequency': 0, u'PhoneNumber': u'123456789'}, 
    {u'PhoneOwner': u'Sarah', u'Frequency': 0, u'PhoneNumber': u'98765431'} 
] 

page = index_dict_in_list(phonebook, 'PhoneNumber', '98765431') 
phonebook[page]['Frequency'] =+ 1 
0

瞧,你有字典的列表,你必須通過列表迭代並檢查該行是否與該特定字典的PhoneNumber匹配。

打開phoneNumberDict到字典中,字典:如果比賽中,以1

with open("CallLog.txt") as connectedNumbers:   
    for line in connectedNumbers: 
     for value in data: 
      if line== value['PhoneNumber']: 
       value['Frequency']+=1 
1

我要提出一個建議增加字典的Frequency。每個鍵將是一個電話號碼,每個值將是一個dict與其餘的信息。通過這種方式,您不需要每次循環查看字典列表。

觀察:

phoneNumberDictionary = { 
         '123456789': {u'PhoneOwner': u'Bob', u'Frequency': 0}, 
         '987654321': {u'PhoneOwner': u'Sarah', u'Frequency': 0} 
         } 
callLogList = ['123456789', 
       '123456789', 
       '123456789', 
       '123456789', 
       '123456789', 
       '987654321', 
       '987654321', 
       '987654321', 
       '987654321', 
       '987654321', 
       '987654321', 
       '987654321', 
       '987654321', 
       '000000000' 
       ] 

for phoneNumber in callLogList: 
    if phoneNumber in phoneNumberDictionary: 
     phoneNumberDictionary[phoneNumber]['Frequency'] += 1 

print (phoneNumberDictionary) 

沒有通過電話號碼清單需要循環每一次,這將是一個更有效的腳本,尤其是電話號碼的名單不斷增加。

我也將for循環的try-except更改爲if語句,因爲每次未包含數字時,這將比捕獲異常更快。我已經包含了一個垃圾電話號碼,以便您可以看到它仍能正常工作。

希望這會有所幫助。

+0

多麼美妙的答案,謝謝。 我從來沒有想過將數據轉化爲字典的字典。這很有道理。 –