2014-11-14 97 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())

感谢所有。