我正在通过编写小程序来学习 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."
最佳答案
您的代码存在一些常见问题,所以让我们从修复这些问题开始。
您有多个项目要呈现给用户,并且您正在对这些值进行硬编码。这对您来说很费力,因为您必须多次重复自己。看看你的选择线,它们基本上都是一样的。您还通过在描述和代码中定义数字链接到什么来重复自己。让我们尝试使用数据结构来简化它。
在这里,我们列出了所有选项 - 一个元组列表,定义了给定食物的名称和项目集。我们在这里使用一套,因为我们不需要订购这些元素。
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
。我们首先必须将字符串更改为数字,然后取走一个(因为 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."
这行得通,打印出多个购买行,但这不是最优的,更好的主意是制作一个包含所有需要元素的更大的购物 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
),但这是基本的想法。
关于python - Python中的购物 list ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10789501/