2014-11-14 67 views
-3

這裏有一個奇怪的位,儘管我確信我正在做一些愚蠢的事情,而剛剛轉換爲Python。我有一個dictdict一個dict(我知道誰家不會喜歡),其代碼如下:字典不區分大小寫,但不知道爲什麼

import sys 

hash = {} 

def update_official(): 
    for keyv in hash: 
     for word in hash[keyv]: 
      if word == 'Alice': 
       hash[keyv][word]["official"] = 1 
      else: 
       hash[keyv][word]["official"] = 0 

def add_case_terms(): 
    new_terms = {} 
    for term_id in hash: 
     for term in dict[term_id]: 
      if term_id not in new_terms: 
       new_terms[term_id] = {} 
      new_terms[term_id][term.title()] = hash[term_id][term] 
      new_terms[term_id][term.upper()] = hash[term_id][term] 
      new_terms[term_id][term.lower()] = hash[term_id][term] 
    for term_id in new_terms: 
     for term in new_terms[term_id]: 
      hash[term_id][term] = new_terms[term_id][term] 

def main(): 
    key1 = 1 
    words = ['Alice','John'] 
    for word in words: 
     if key1 not in dict: 
      hash[key1] = {} 
     hash[key1][word] = {"official":0,"other_info":5} 
    add_case_terms() 
    update_official() 

    for key in hash: 
     for term in hash[key]: 
      print str(term) + " has official: " + str(hash[key][term]["official"]) 

    print "\nAmending 'alice'.\n" 
    hash[1]['alice']["official"] = 1 

    for key in hash: 
     for term in hash[key]: 
      print str(term) + " has official: " + str(hash[key][term]["official"]) 


if __name__ == "__main__": 
    sys.exit(main()) 

我得到的輸出是:

john has official: 0 
Alice has official: 0 
ALICE has official: 0 
John has official: 0 
JOHN has official: 0 
alice has official: 0 

Amending 'alice'. 

john has official: 0 
Alice has official: 1 
ALICE has official: 1 
John has official: 0 
JOHN has official: 0 
alice has official: 1 

我不要什麼」不明白爲什麼每個alice鍵得到更新,而不僅僅是對應於正確的情況。有任何想法嗎?

+9

命名你的詞典'詞典'是一個壞的舉動,因爲它影響內置。 – jonrsharpe 2014-11-14 13:46:43

+1

你可以顯示一些輸出。如果我必須猜測它不是這個詞典不區分大小寫,而是與你調用term.upper()和term有關。lower() – user2097159 2014-11-14 13:48:03

+0

你更新'main'中的'dict [1] ['alice']',並在'update_official'中更新'word =='Alice''的情況 - 爲什麼你會對輸出感到驚訝? – jonrsharpe 2014-11-14 13:48:51

回答

1

興趣點。

不要通過已存在的名稱調用變量。 dict()是內置的,不應該用作變量名稱。嘗試一些簡單的操作即可。my_dict

您不需要嵌套循環來從字典中獲取鍵/值對;使用.items()返回兩者的元組:

for key, value in my_dict.items(): 
    print key, value 

如果這是敏感的字典是簡單的目標 - 做的情況下!你也得太多;)

您可以使用getter和setter方法,如:

def set_insensitive(my_dict, str_key, my_val): 
    my_dict[str_key.lower()] = myval 

def get_insensitive(my_dict, str_key): 
    return my_dict[str_key.lower()] 

而且你可以創建一個區分大小寫一個像這樣一個新的不區分大小寫的字典:

def create_insensitive(my_dict): 
    new_dict = {} 
    for str_key, value in my_dict.items(): 
     new_dict[str_key.lower()] = value 
    return new_dict 

或理解:

def create_insensitive(my_dict): 
    return = { str_key.lower() : value for str_key, value in my_dict.items() } 
+0

謝謝我接受你的觀點,儘管我試圖做的是確保它是區分大小寫的,就像默認情況下一樣。爲什麼當我更新'愛麗絲'時,它是否會改變'ALICE'和'alice'的值?對我來說似乎很奇怪。 – 2014-11-14 14:13:33

1

這只是因爲你有多個鍵爲相同可變對象。您的結構是這樣的:

value = {"official":0,"other_info":5} 
hash[1]['ALICE'] = value 
hash[1]['alice'] = value 
hash[1]['Alice'] = value 

注意,所有這些任務都使用相同的value使用不同的密鑰。稍後,當您執行hash[keyv][word]["official"] = X時,使用word的各種值中的哪一個並不重要,因爲它們導致相同的對象。

 new_terms[term_id][term.title()] = hash[term_id][term] 
     new_terms[term_id][term.upper()] = hash[term_id][term] 
     new_terms[term_id][term.lower()] = hash[term_id][term] 

是您的代碼的一部分,它創建各個鍵,都指向同一個對象。

+0

謝謝,最好的解釋。有沒有一種簡單的方法來創建不指向現有字典的新對象?你會遍歷該字典的每個val並存儲在一個新的字典? – 2014-11-14 14:31:29

+0

您可以通過多種方式製作副本,例如'dict(d)'或'd.copy()'創建一個與'd'具有相同內容的新字典。 'copy'模塊還包含'copy'和'deepcopy'功能。 – 2014-11-14 15:01:50

+0

剛看到它,它的工作原理。非常感謝你。我也做了一些閱讀,並沒有意識到,python不喜歡複製! http://henry.precheur.org/python/copy_list.html – 2014-11-14 15:06:48

0

感謝您的幫助。事實證明,在這種情況下重要的是不要影響字典。解決方法如下:

import sys 
 

 
my_dict = {} 
 

 
def update_official(): 
 
    for keyv in my_dict: 
 
     for word in my_dict[keyv]: 
 
      if word == 'Alice': 
 
       my_dict[keyv][word]["official"] = 1 
 
      else: 
 
       my_dict[keyv][word]["official"] = 0 
 

 
def add_case_terms(): 
 
    new_terms = {} 
 
    for term_id,val in my_dict.items(): 
 
     for term in my_dict[term_id]: 
 
      if term_id not in new_terms: 
 
       new_terms[term_id] = {}   
 
      new_terms[term_id][term.title()] = dict(my_dict[term_id][term]) 
 
      new_terms[term_id][term.upper()] = dict(my_dict[term_id][term]) 
 
      new_terms[term_id][term.lower()] = dict(my_dict[term_id][term]) 
 
    for term_id in new_terms: 
 
     for term in new_terms[term_id]: 
 
      my_dict[term_id][term] = dict(new_terms[term_id][term]) 
 

 
def set_insensitive(my_dict, str_key, my_val): 
 
    my_dict[str_key.lower()] = myval 
 
    my_dict[str_key.upper()] = myval 
 
    my_dict[str_key.title()] = myval 
 
    
 

 
def main(): 
 
    key1 = 1 
 
    words = ['Alice','John'] 
 
    for word in words: 
 
     if key1 not in my_dict: 
 
      my_dict[key1] = {} 
 
     my_dict[key1][word] = {"official":0,"other_info":5} 
 
    add_case_terms() 
 
    update_official() 
 
     
 
    for key in my_dict: 
 
     for term in my_dict[key]: 
 
      print str(term) + " has official: " + str(my_dict[key][term]["official"]) 
 
      
 
    print "\nAmending 'alice'.\n" 
 
    my_dict[1]['alice']["official"] = 1 
 
    
 
    for key in my_dict: 
 
     for term in my_dict[key]: 
 
      print str(term) + " has official: " + str(my_dict[key][term]["official"]) 
 

 

 
if __name__ == "__main__": 
 
    sys.exit(main())

感謝所有。