我正在通过制作小程序来学习Python(以及一般的编程)。以下是一个基本的购物计划,它将根据所选食品返回要购买的商品清单。
我想改进它并允许用户一次选择几种食物(例如用户输入为“1,2,3”)并根据该列表返回成分列表。
我应该采取什么样的方法?我正在使用Python 2.7,这是我现有的代码:
mm_soup = ['minced meat', 'potatoes', 'frozen vegetable']
sunday_soup = ['chicken with bones', 'noodles', 'soup vegetable']
gulas = ['pork meat', 'food cream', 'potatoes', 'onion', 'frozen peas']
print "What would you like to cook on weekend?"
print "Here are the options:"
print "1. Minced Meat Soup"
print "2. Sunday Soup"
print "3. Gulas"
choose = raw_input("> ")
if choose == '1':
print "Buy", ", ".join(mm_soup) + "."
elif choose == '2':
print "Buy", ", ".join(sunday_soup) + "."
elif choose == '3':
print "Buy", ", ".join(gulas) + "."
else:
print "Hmmm. No such food on the list."
答案 0 :(得分:7)
您的代码存在一些常见问题,因此我们首先修复这些问题。
您想要向用户显示多个项目,并且您正在对这些值进行硬编码。这给你带来了很多努力,因为你必须经常重复自己。看看你的选择线,它们基本上都是一样的。您还可以通过定义数字在描述和代码中链接到的内容来重复自己。让我们尝试用数据结构来简化它。
在这里,我们列出了所有选项 - 元组列表,定义了给定食物的名称和项目集。我们在这里使用一套,因为我们不需要订购商品。
options = [
("Minced Meat Soup", {'minced meat', 'potatoes', 'frozen vegetable'}),
("Sunday Soup", {'chicken with bones', 'noodles', 'soup vegetable'}),
("Gulas", {'pork meat', 'food cream', 'potatoes', 'onion', 'frozen peas'}),
]
这为我们提供了良好的数据结构。
然后我们可以提出问题,而不是手动构建它,我们可以使用循环从我们的选项列表构建它:
print "What would you like to cook on weekend?"
print "Here are the options:"
for option, (name, values) in enumerate(options, 1):
print str(option)+". "+name
请注意the enumerate()
builtin的使用,以便为我们提供选项的编号。当你想从1开始,而Python正常从0开始计算时,我们也会传递它。
这为我们提供了输出,但我们现在可以轻松添加更多项目而无需修改现有代码。我们像以前一样问,然后我们可以简单地从列表中获取他们给我们的索引,而不是加载if
/ elif
s。我们首先要将字符串更改为数字,然后取出一个(因为Python从0开始计数)。这给了我们:
_, values = options[int(choose)-1]
(使用元组解包来忽略第一个值,因为它是我们不需要的名称)。
现在唯一的问题是,例如,如果用户输入的数字超出范围或单词,将会发生什么。您可以在转换为int并使用它之前检查它,但它只是尝试Pythonic,并在失败时捕获抛出的异常。例如:
try:
_, values = options[int(choose)-1]
print "Buy", ", ".join(values) + "."
except (IndexError, ValueError):
print "Hmmm. No such food on the list."
这使得整个程序变得更小,并且还注意到添加新项目是多么容易,只需将它们添加到列表中即可。
那么我们如何处理多个项目?嗯,现在也很简单。我们可以接受用户的输入,分成逗号,并删除值以删除任何空格,然后执行我们之前所做的相同操作:
for choice in choose.split(","):
choice = choice.strip()
try:
_, values = options[int(choice)-1]
print "Buy", ", ".join(values) + "."
except (IndexError, ValueError):
print "Hmmm. No such food on the list."
这样可以打印出多条购买线,但这不是最佳选择,更好的办法就是制作一个包含所有需要物品的更大的购物清单。
我们可以通过在循环时构建所有项目的集合来构建它,然后打印出该集合。
shopping_list = []
for choice in choose.split(","):
choice = choice.strip()
try:
_, values = options[int(choice)-1]
shopping_list.append(values)
except (IndexError, ValueError):
print "Hmmm. No such food on the list."
然而,这有点低效和丑陋。 Python有一些内置的功能来构建列表 - list comprehensions。我们可以这样做:
try:
shopping_list = [options[int(choice.strip())-1][3] for choice in choose.split(",")]
except (IndexError, ValueError):
print "Hmmm. No such food on the list."
现在我们需要打印出列表中的所有值。请记住,这是一个集合列表,因此", ".join()
不会完全符合我们的要求。我们有两种选择。我们可以使用生成器表达式首先连接集合,然后加入连接的字符串:
print "Buy " + ", ".join(", ".join(values) for values in shopping_list) + "."
或者,我们可以使用itertools.chain.from_iterable()
返回一个展平的迭代器:
print "Buy " + ", ".join(itertools.chain.from_iterable(shopping_list)) + "."
这给了我们:
import itertools
options = [
("Minced Meat Soup", {'minced meat', 'potatoes', 'frozen vegetable'}),
("Sunday Soup", {'chicken with bones', 'noodles', 'soup vegetable'}),
("Gulas", {'pork meat', 'food cream', 'potatoes', 'onion', 'frozen peas'}),
]
print "What would you like to cook on weekend?"
print "Here are the options:"
for option, (name, values) in enumerate(options, 1):
print str(option)+". "+name
choose = raw_input("> ")
try:
shopping_list = [options[int(choice.strip())-1][1] for choice in choose.split(",")]
print "Buy " + ", ".join(itertools.chain.from_iterable(shopping_list)) + "."
except (IndexError, ValueError):
print "Hmmm. No such food on the list."
产生类似的东西:
What would you like to cook on weekend?
Here are the options:
1. Minced Meat Soup
2. Sunday Soup
3. Gulas
> 1, 2
Buy potatoes, frozen vegetable, minced meat, chicken with bones, noodles, soup vegetable.
这个简短,易于扩展,功能良好。还有一些其他问题你可以处理(你想如何处理同一个项目的多个?你可能想要查看collections.Counter
),但这是基本的想法。
答案 1 :(得分:1)
我想你可以拆分输入的字符串并遍历其元素:
choose = raw_input("> ")
for choice in choose.split(', '): #split by comma and space
if choice == '1':
print "Buy", ", ".join(mm_soup) + "."
elif choice == '2':
print "Buy", ", ".join(sunday_soup) + "."
elif choice == '3':
print "Buy", ", ".join(gulas) + "."
else:
print "Hmmm. No such food on the list."
或类似的东西:
choose = raw_input("> ");
selected = choose.split(', ') #split by comma and space
suggestion = '';
if '1' in selected :
suggestion += ", ".join(mm_soup)
if '2' in selected :
suggestion += ", ".join(sunday_soup)
if '3' in selected :
suggestion += ", ".join(gulas)
if len(suggestion) > 0:
print "Buy " + suggestion + "."
else:
print "Hmmm. No such food on the list."