Python 使用 any() 函数过滤数组

Python filtering array using the any() function

我正在尝试编写一个通过接受两个输入来推荐书籍的程序:

所需的属性输入应该是一个字符串,例如 sh 或 shf(顺序无关紧要,因此字符串 "shf" 被视为与 "fhs" 相同)。

我已经成功创建了一个过滤器,可以过滤掉超过客户最高成本的书籍。但是,该函数继续输出用户提供的 any 类别中的任何书籍,而不是满足 all of the categories 的书籍作为必需的(例如,既有奇幻又有浪漫色彩的书籍)。我尝试用 all() 函数替换 any() 函数,但这似乎无法解决问题。谁能就我哪里出错提供建议?

def recommend_books(max_price, cats):
    if not set(cats).issubset(set(book_categories)):
        raise ValueError(f'{cats} contains an invalid category code')
    cats_f = [cat for cat_i, cat in book_categories.items() if cat_i in set(cats)]
    return [book for book, price, cats in book_data
            if (price <= max_price and all(True for cat in cats if cat in cats_f))]


book_data = [["Harry Potter", 8, ["fantasy", "romance"]],
             ["IT", 11, ["horror", "fantasy"]],
             ["Star Wars", 22, ["scifi", "romance", "fantasy"]],
             ["Carrie", 13, ["horror"]],
             ["Lord of the Rings", 29, ["fantasy", "romance"]]
             ]

book = [book[0] for book in book_data]

book_categories = {}
for book, price, category in book_data:
    for cat in category:
        cat_initial = cat[0]
        if not cat_initial in book_categories:
            book_categories[cat_initial] = cat

recommend_books(25, "hf")
# Output should be an array of the Titles of the suitable book recommendations
# I.e. ["IT"]

这个例子的输出是:['Harry Potter', 'IT', 'Star Wars', 'Carrie'] 这是所有小于 25 的恐怖和奇幻书籍的数组, 所以过滤器似乎没有正常工作。

在您发表评论后编辑我的答案:

您在过滤中的第二个条件应该是:

all(elem in cats for elem in cats_f)

以及完整的功能:

def recommend_books(max_price, cats):
        if not set(cats).issubset(set(book_categories)):
            raise ValueError(f'{cats} contains an invalid category code')
        cats_f = [cat for cat_i, cat in book_categories.items() if cat_i in set(cats)]
        return [book for book, price, cats in book_data 
                if (price <= max_price and **all (True for cat in cats if cat in cats_f))**]

遍历您想要的所有类别(cat_f),并检查它们是否都在图书的类别中(cats)

这会产生您想要的输出。

应该这样做:

def recommend_books(max_price, cats):
    if not set(cats).issubset(set(book_categories)):
        raise ValueError(f'{cats} contains an invalid category code')
    cats_f = [cat for cat_i, cat in book_categories.items() if cat_i in set(cats)]
    return [book for book, price, cats in book_data
            if (price <= max_price and all (cat in cats for cat in cats_f))]