Python - 使用多个列表

问题描述 投票:0回答:6

为什么这个程序不起作用?

available_toppings = ["mushrooms", "olives", "green peppers", "pepperoni", "pineapple", "extra cheese"]

requested_toppings = ['mushrooms', 'olives', 'extra cheese']

if requested_toppings in available_toppings:
    for requested_topping in requested_toppings:
        print("Adding " + requested_topping.title() + ".")
    print("Finalising your order.")

else:
    print("sorry we dont have these toppings")

而输出是

sorry we dont have these toppings
python for-loop if-statement
6个回答
3
投票

你想检查requested_toppings列表是available_toppings的子集。

你可以使用set.issubset()函数。

available_toppings = ["mushrooms", "olives", "green peppers", "pepperoni", "pineapple", "extra cheese"]

requested_toppings = ['mushrooms', 'olives', 'extra cheese']

if set(requested_toppings).issubset(available_toppings):
    for requested_topping in requested_toppings:
        print("Adding " + requested_topping.title() + ".")
    print("Finalising your order.")

else:
    print("sorry we dont have these toppings")

这会导致

Adding Mushrooms.
Adding Olives.
Adding Extra Cheese.
Finalising your order.

如果你用olives中的shrimps替换requested_toppings,你会得到

sorry we dont have these toppings

正如所料。


1
投票

python,all()any()有两个漂亮的功能。尝试使用all()

available_toppings = ["mushrooms", "olives", "green peppers", "pepperoni", "pineapple", "extra cheese"]

requested_toppings = ['mushrooms', 'olives', 'extra cheese']

if all(topping in available_toppings for topping in requested_toppings):
    for requested_topping in requested_toppings:
        print("Adding " + requested_topping.title() + ".")
    print("Finalising your order.")

else:
    print("sorry we dont have these toppings")

您的代码有什么问题?您检查列表是否是另一个列表的元素,如:

>>> [1,2] in [1,2,3]
False
>>> [1,2] in [[1,2],3]
True

1
投票

看起来你切换了for循环和if条件的顺序。也许你想要以下内容:

  • 对于每个请求的顶部,检查它是否在可用的浇头中

您可以尝试以下操作,而不是检查整个请求列表是否在其他可用列表中:

available_toppings = ["mushrooms", "olives", "green peppers", "pepperoni", "pineapple", "extra cheese"]

requested_toppings = ['mushrooms', 'olives', 'extra cheese']

for requested_topping in requested_toppings:
    if requested_topping in available_toppings:
        print("Adding " + requested_topping.title() + ".")
    else:
        print("sorry we dont have these toppings")

print("Finalising your order.")

0
投票

不完全是你想要的,但很容易适应。

available_toppings = ["mushrooms", "olives", "green peppers", "pepperoni", "pineapple", "extra cheese"]
requested_toppings = ["mushrooms", "olives", "extra cheese", "onions"]
RQ = []
for requested in requested_toppings:
    RQ.append(requested)
for available in available_toppings:
    for R in RQ:
        if R in available:print "We have :",R
if R not in available:print "Do not Have : ",R 
RESULTS:
We have : mushrooms
We have : olives
We have : extra cheese
Do not Have :  onions

0
投票

试试这个:

available_toppings = ["mushrooms", "olives", "green peppers", "pepperoni", "pineapple", "extra cheese"]

requested_toppings = ['mushrooms', 'olives', 'extra cheese']
hasItem = True
for requested_topping in requested_toppings:
    if requested_topping not in available_toppings:   
        hasItem = False   
if hasItem:
    for requested_topping in requested_toppings:
        print("Adding " + requested_topping.title() + ".")
    print("Finalising your order.") 
else:
        print("sorry we dont have these toppings") 

0
投票

对于一种不同的方法 - 可能并不比现有的答案更好,实际上可能更糟 - 但它确实以简单的方式展示了一些有趣的想法。

try:
    output = []
    # Notice that we're not pre-checking here. So this will
    # work even if requested_toppings is a one-shot iterator.
    for requested_topping in requested_toppings:
        if requested_topping in available_toppings:
            # Don't actually print, because that's irreversible;
            # do it "off to the side" or "in a transaction" that we
            # can "commit" or "rollback".
            output.append("Adding " + requested_topping.title() + ".")
        else:
            # Here's where we "rollback"
            raise KeyError(requested_topping)
except KeyError:
    # Discard the "transaction" by just not doing anything with it.
    # And now we're out of the "pure" section of the code, so we
    # can do I/O without worrying.
    print("sorry we dont have these toppings")
else:
    # "Commit" by just printing the output.
    print(*output, sep='\n')
    # And again, we're out of the pure code now, so just print
    print("Finalising your order.")

再解释一下:

这个问题唯一棘手的部分是你不想开始添加配料,如果你没有全部(因为那时你会给顾客错误的希望 - 你可能不得不丢掉一整块披萨) 。

显而易见的解决方案是通过使用子集测试(如在Dmitri Chubarov's answer中)或all循环(如在Amaro Vita's中)或仅使用for语句来检查是否预先提供了所有浇头。在这种情况下,这样做很好,所以这就是你应该做的。

但是有些问题你不能这样做。也许requested_toppings是一个迭代器,你要么不能重复,要么重复是非常昂贵的。或者可能提前测试非常困难,您所能做的就是尝试所有操作,看看其中一个操作是否失败。对于那些问题,你需要一些方法来避免做昂贵和不可逆转的事情,比如添加披萨配料或发射导弹。那是你使用像这样的解决方案。

当然你可以做同样的事情,没有例外,只需使用break进行回滚,并使用else上的for子句进行提交,但似乎更多的人发现for ... else比异常更令人困惑。

最后一件事:如果你把available_toppings变成一个集合而不是列表,所有的解决方案,包括我的解决方案都会好一些。你唯一要做的就是in测试,这就是为什么设置。 (而且它不仅仅是一个概念上的差异,而是一个性能 - 你可以在一个恒定时间内对一组进行in测试,而对于一个列表,它必须检查每个测试的所有值。)

© www.soinside.com 2019 - 2024. All rights reserved.