python – 循环字典值
我目前有一个程序,它读取文本文件并根据内部输入回答一组查询.它有助于弄清楚母亲是谁的孩子受到质疑.我现在更进一步,重新处理这些输出,以显示完整的族树.
这是包含左侧父母和右侧孩子的文本文件.下面是要求的查询,输出后面跟着查询. Sue: Chad,Brenda,Harris Charlotte: Tim Brenda: Freddy,Alice Alice: John,Dick,Harry mother Sue ancestors Harry ancestors Bernard ancestors Charlotte >>> Mother not known >>> Alice,Sue >>> Unknown Person >>> No known ancestors 该程序能够确定母亲是谁(感谢Kampu的帮助),但我现在正试图了解如何获取这个值,并可能将其附加到新的列表或字典中,在那里无限循环查找任何可能的祖父母. def lookup_ancestor(child): ancestor = REVERSE_MAP.get(child) if ancestor: ANCESTOR_LIST_ADD.append(ancestor) if ancestor not in LINES[0:]: print("Unknown person") else: print("No known ancestors") 这就是我到目前为止,REVERSE_MAP将每个子项映射到字典中的父项.然后我将父母列入一个新的名单,我打算再次运行以确定他们的父母是谁.我在这一点上陷入困??境,因为我找不到一种优雅的方式来执行整个过程而不创建三个新的列表来保持循环.目前它的设置方式,我假设我需要通过for循环追加它们,或者之后只需将split()值相加以保持所有值相互之间.理想情况下,我想学习如何循环这个过程,找出每个问题祖先是谁. 我觉得好像我已经掌握了它应该如何看,但我对Python的了解阻止了我的试错方法的时间效率. 任何帮助将不胜感激! 编辑:链接 – http://pastebin.com/vMpT1GvX 编辑2: def process_commands(commands,relation_dict): '''Processes the output''' output = [] for c in commands: coms = c.split() if len(coms) < 2: output.append("Invalid Command") continue action = coms[0] param = coms[1] def mother_lookup(action,param,relation_dict): output_a = [] if action == "mother": name_found = search_name(relation_dict,param) if not name_found: output_a.append("Unknown person") else: person = find_parent(relation_dict,param) if person is None: output_a.append("Mother not known") else: output_a.append(person) return output_a def ancestor_lookup(action,relation_dict): output_b = [] if action == "ancestors": name_found = search_name(relation_dict,param) if not name_found: output_b.append("Unknown person") else: ancestor_list = [] person = param while True: person = find_parent(relation_dict,person) if person == None: break else: ancestor_list.append(person) if ancestor_list: output_b.append(",".join(ancestor_list)) else: output_b.append("No known ancestors") return output_b def main(): '''Definining the file and outputting it''' file_name = 'relationships.txt' relations,commands = read_file(file_name) #Process Relqations to form a dictionary of the type #{parent: [child1,child2,...]} relation_dict = form_relation_dict(relations) #Now process commands in the file action = process_commands(commands,relation_dict) param = process_commands(commands,relation_dict) output_b = ancestor_lookup(action,relation_dict) output_a = mother_lookup(action,relation_dict) print('n'.join(output_a)) print ('n'.join(output_b)) if __name__ == '__main__': main() 解决方法
正如@NullUserException所说,树(或类似的树)是一个不错的选择.
我发布的答案与您为此问题所选择的内容完全不同. 您可以定义一个知道其名称的Person对象,并跟踪其父级是谁.父级不是名称,而是另一个Person对象! (有点像链表).然后,您可以将人员集合保留为单个列表. 在解析文件时,您不断将人员添加到列表中,同时使用正确的对象更新其子/父属性. 给予任何人后,只需打印属性即可找到关系 以下是一种可能的实现(On Python-2.6).在这种情况下,文本文件只包含关系.稍后使用交互式输入触发查询 class Person(object): """Information about a single name""" def __init__(self,name): self.name = name self.parent = None self.children = [] def search_people(people,name): """Searches for a name in known people and returns the corresponding Person object or None if not found""" try: return filter(lambda y: y.name == name,people)[0] except IndexError: return None def search_add_and_return(people,name): """Search for a name in list of people. If not found add to people. Return the Person object in either case""" old_name = search_people(people,name) if old_name is None: #First time entry for the name old_name = Person(name) people.append(old_name) return old_name def read_file(file_name,people): fp = open(file_name,'r') while True: l = fp.readline() l.strip('n').strip() if not l: break names = l.split(':') mother = names[0].strip() children = [x.strip() for x in names[1].split(',')] old_mother = search_add_and_return(people,mother) #Now get the children objects child_objects = [] for child in children: old_child = search_add_and_return(people,child) child_objects.append(old_child) #All children have been gathered. Link them up #Set parent in child and add child to parent's 'children' old_mother.children.extend(child_objects) for c in child_objects: c.parent = old_mother fp.close() def main(): file_name = 'try.txt' people = [] read_file(file_name,people) #Now lets define the language and start a loop while True: command = raw_input("Enter your command or 0 to quitn") if command == '0': break coms = command.split() if len(coms) < 2: print "Wrong Command" continue action = coms[0] param = coms[1] if action == "mother": person = search_people(people,param) if person == None: print "person not found" continue else: if person.parent is None: print "mother not known" else: print person.parent.name elif action == "ancestors": person = search_people(people,param) if person == None: print "person not found" continue else: ancestor_list = [] #Need to keep looking up parent till we don't reach a dead end #And collect names of each ancestor while True: person = person.parent if person is None: break ancestor_list.append(person.name) if ancestor_list: print ",".join(ancestor_list) else: print "No known ancestors" if __name__ == '__main__': main() 编辑 由于您希望简单易懂,因此这是一种使用词典(单个词典)来执行您想要的操作的方法 基本思路如下.您解析文件以形成一个字典,其中键是母亲,值是儿童的列表.因此,当您的示例文件被解析时,您会得到一个字典 relation_dict = {'Charlotte': ['Tim'],'Sue': ['Chad','Brenda','Harris'],'Alice': ['John','Dick','Harry'],'Brenda': ['Freddy','Alice']} 要查找父级,只需搜索名称是否在字典值中,如果找到则返回密钥.如果找不到母亲,则返回无 mother = None for k,v in relation_dict.items(): if name in v: mother = k break return mother 如果你想找到所有的祖先,你只需要重复这个过程,直到返回None ancestor_list = [] person = name while True: person = find_parent(relation_dict,person) if person == None: #Top of the ancestor chain found break else: ancestor_list.append(person) 这是Python-2.6中的一个实现.它假定您的文本文件的结构使得首先存在所有关系,然后是空白行,然后是所有命令. def read_file(file_name): fp = open(file_name,'r') relations = [] commands = [] reading_relations = True for l in fp: l = l.strip('n') if not l: reading_relations = False continue if reading_relations: relations.append(l.strip()) else: commands.append(l.strip()) fp.close() return relations,commands def form_relation_dict(relations): relation_dict = {} for l in relations: names = l.split(':') mother = names[0].strip() children = [x.strip() for x in names[1].split(',')] existing_children = relation_dict.get(mother,[]) existing_children.extend(children) relation_dict[mother] = existing_children return relation_dict def search_name(relation_dict,name): #Returns True if name occurs anywhere in relation_dict #Else return False for k,v in relation_dict.items(): if name ==k or name in v: return True return False def find_parent(relation_dict,param): #Finds the parent of 'param' in relation_dict #Returns None if no mother found #Returns mother name otherwise mother = None for k,v in relation_dict.items(): if param in v: mother = k break return mother def process_commands(commands,relation_dict): output = [] for c in commands: coms = c.split() if len(coms) < 2: output.append("Invalid Command") continue action = coms[0] param = coms[1] if action == "mother": name_found = search_name(relation_dict,param) if not name_found: output.append("person not found") continue else: person = find_parent(relation_dict,param) if person is None: output.append("mother not known") else: output.append("mother - %s" %(person)) elif action == "ancestors": name_found = search_name(relation_dict,param) if not name_found: output.append("person not found") continue else: #Loop through to find the mother till dead - end (None) is not reached ancestor_list = [] person = param while True: person = find_parent(relation_dict,person) if person == None: #Top of the ancestor found break else: ancestor_list.append(person) if ancestor_list: output.append(",".join(ancestor_list)) else: output.append("No known ancestors") return output def main(): file_name = 'try.txt' relations,commands = read_file(file_name) #Process Relqations to form a dictionary of the type {parent: [child1,...]} relation_dict = form_relation_dict(relations) print relation_dict #Now process commands in the file output = process_commands(commands,relation_dict) print 'n'.join(output) if __name__ == '__main__': main() 样本输入的输出是 mother not known Alice,Sue person not found No known ancestors EDIT2 如果你真的想将它进一步分解为函数,那么这就是process_commands的外观 def process_mother(relation_dict,name): #Processes the mother command #Returns the ouput string output_str = '' name_found = search_name(relation_dict,name) if not name_found: output_str = "person not found" else: person = find_parent(relation_dict,name) if person is None: output_str = "mother not known" else: output_str = "mother - %s" %(person) return output_str def process_ancestors(relation_dict,name): output_str = '' name_found = search_name(relation_dict,name) if not name_found: output_str = "person not found" else: #Loop through to find the mother till dead - end (None) is not reached ancestor_list = [] person = name while True: person = find_parent(relation_dict,person) if person == None: #Top of the ancestor found break else: ancestor_list.append(person) if ancestor_list: output_str = ",".join(ancestor_list) else: output_str = "No known ancestors" return output_str def process_commands(commands,relation_dict): output = [] for c in commands: coms = c.split() if len(coms) < 2: output.append("Invalid Command") continue action = coms[0] param = coms[1] if action == "mother": new_output = process_mother(relation_dict,param) elif action == "ancestors": new_output = process_ancestors(relation_dict,param) if new_output: output.append(new_output) return output (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |