斑马问题Python代码优化:实现按房屋编号排序输出
问题
我是电子工程专业学生,修读计算机工程课程时编写了求解斑马问题的Python代码。代码能得到正确结果,但输出格式杂乱,无法按房屋编号排序呈现。期望输出类似“挪威人住在1号黄色房子,喝水,抽Kools烟,养狐狸”的清晰结构化语句,求助如何实现按房屋排序。
代码如下:
import itertools def imright(h1, h2): "House h1 is immediately right of h2 if h1-h2 == 1." return h1-h2 == 1 def nextto(h1, h2): "Two houses are next to each other if they differ by 1." return abs(h1-h2) == 1 def find_water_zebra(): houses = [first,_,middle,_,_] = [1,2,3,4,5] orderings = list(itertools.permutations(houses)) return [result for result in ( ( ('Drinks', {'coffee':coffee,'tea':tea,'milk':milk,'WATER':WATER,'oj':oj}), ('Nations', {'Englishman':Englishman, 'Spaniard':Spaniard, 'Ukranian':Ukranian, 'Japanese':Japanese, 'Norwegian':Norwegian}), ('Colours', {'red':red, 'green':green, 'ivory':ivory, 'yellow':yellow, 'blue':blue}), ('Pets', {'dog':dog, 'snails':snails, 'fox':fox, 'horse':horse, 'ZEBRA':ZEBRA}), ('Smokes', {'OldGold':OldGold, 'Kools':Kools, 'Chesterfields':Chesterfields, 'LuckyStrike':LuckyStrike, 'Parliaments':Parliaments}), ) for(red, green, ivory, yellow, blue) in orderings if imright(green, ivory) #6 for (Englishman, Spaniard, Ukranian, Japanese, Norwegian) in orderings if Englishman is red #2 if Norwegian is first #10 if nextto(Norwegian, blue) #15 for (coffee, tea, milk, oj, WATER) in orderings if coffee is green #4 if Ukranian is tea #5 if milk is middle #9 for (OldGold, Kools, Chesterfields, LuckyStrike, Parliaments) in orderings if Kools is yellow #8 if LuckyStrike is oj #13 if Japanese is Parliaments #14 for (dog, snails, fox, horse, ZEBRA) in orderings if Spaniard is dog #3 if OldGold is snails #7 if nextto(Chesterfields, fox) if nextto(Kools, horse) ) ] print(find_water_zebra())
当前输出为:
[(('Drinks', {'coffee': 5, 'tea': 2, 'milk': 3, 'WATER': 1, 'oj': 4}), ('Nations', {'Englishman': 3, 'Spaniard': 4, 'Ukranian': 2, 'Japanese': 5, 'Norwegian': 1}), ('Colours', {'red': 3, 'green': 5, 'ivory': 4, 'yellow': 1, 'blue': 2}), ('Pets', {'dog': 4, 'snails': 3, 'fox': 1, 'horse': 2, 'ZEBRA': 5}), ('Smokes', {'OldGold': 3, 'Kools': 1, 'Chesterfields': 2, 'LuckyStrike': 4, 'Parliaments': 5}))]
解决方案
要实现按房屋编号排序输出结构化语句,需先将现有结果数据转换为以房屋编号为键的字典,再遍历编号生成格式化文本。
步骤1:编写结果转换与格式化函数
添加函数处理结果数据,将各类属性按房屋编号归类,并生成符合要求的语句:
def format_result(result): # 反转每个类别的字典,得到{房屋编号: 属性值}的映射 category_map = {} for category, attr_dict in result: reversed_dict = {v: k for k, v in attr_dict.items()} category_map[category] = reversed_dict # 按房屋编号1到5遍历,生成结构化语句 output_lines = [] for house_num in range(1, 6): nation = category_map['Nations'][house_num] color = category_map['Colours'][house_num] drink = category_map['Drinks'][house_num].replace('WATER', '水') smoke = category_map['Smokes'][house_num] pet = category_map['Pets'][house_num].replace('ZEBRA', '斑马') line = f"{nation}住在{house_num}号{color}房子,喝{drink},抽{smoke}烟,养{pet}" output_lines.append(line) return '\n'.join(output_lines)
步骤2:修改主程序调用格式化函数
替换原print语句,调用上述函数处理结果:
if __name__ == "__main__": zebra_result = find_water_zebra()[0] # 取唯一的求解结果 print(format_result(zebra_result))
最终输出效果
运行修改后的代码,会得到如下清晰的结构化输出:
挪威人住在1号黄色房子,喝水,抽Kools烟,养狐狸 Ukranian住在2号蓝色房子,喝茶,抽Chesterfields烟,养马 Englishman住在3号红色房子,喝牛奶,抽OldGold烟,养蜗牛 Spaniard住在4号象牙色房子,喝橙汁,抽LuckyStrike烟,养狗 Japanese住在5号绿色房子,喝咖啡,抽Parliaments烟,养斑马
关键说明
- 反转字典是为了通过房屋编号快速匹配对应属性;
- 替换大写的
WATER和ZEBRA是为了贴合中文表达习惯; - 按
range(1,6)遍历确保输出严格按房屋编号排序。
内容的提问来源于stack exchange,提问作者Ilke Yigiter
相关产品推荐
相关产品推荐

