检查“frodo”是否可以是“fr*d*”

2024-09-29 17:16:52 发布

您现在位置:Python中文网/ 问答频道 /正文

下面的代码

部分是('frodo', 'fradi'), ('frodo', 'crodo'), ('frodo', 'abc123'), ('frodo', 'abc123'), ('frodo', 'frodoc'), ('fradi', 'crodo'), ('fradi', 'abc123'), ('fradi', 'abc123'), ('fradi', 'frodoc'), ('crodo', 'abc123')之一

班努集团是["fr*d*", "abc1**"]

函数解决方案检查部件[i]是否可以是ban_组[i]

我所期望的是

当part为('frodo','fradi')时,part[0]可以是ban_组[0],part[1]不能是ban_组[1]。所以这是假的

当部件为('frodo','abc123')时,部件[0]可以是ban_组[0],部件[1]可以是ban_组[1]。所以这是真的,所以在候选名单中添加部分

但它没有像我预期的那样工作。我真的不明白问题出在哪里

你能帮我吗

from itertools import combinations

def check_id(user, ban):
    for i in range(len(ban)):
        if ban[i] == '*':
            continue
        elif user[i] != ban[i]:
            return False
    return True

candidates = []
def solution(user_group, ban_group):
    for part in combinations(user_group, len(ban_group)):
        for i in range(len(part)):
            if check_id(part[i], ban_group[i]) is True:
                candidates.append(part)
    return candidates

print(solution(["frodo", "fradi", "crodo", "abc123", "frodoc"], ["fr*d*", "abc1**"]))

Tags: inforlenreturn部件groupcandidatespart
3条回答
    for i in range(len(part)):
        if check_id(part[i], ban_group[i]) is True:
            candidates.append(part)

这将比较从partban_group对应的元素的每个元素,以及匹配的每个元素的整个partcandidates

您想要的(如果我理解正确的话)是对照整个ban_group检查来自part的每个元素,以查看是否有任何ban_group元素匹配。然后,您需要查看这些结果,并查看是否所有的part元素都匹配,并且可能对候选元素进行一次append

使用for循环来完成这项工作可能会很棘手,而且简单的想法需要大量的代码。更好的方法是使用内置的anyall函数,这些函数可以传递给生成器表达式,以便轻松处理整个列表。然后,您可以使用函数来命名流程的每个步骤。对于整个循环,我们也可以使用列表理解,而不是append将每个结果添加到新列表中

def is_banned(user, ban_group):
    # use `any` to see if the user matches any of the ban patterns.
    return any(check_id(user, ban) for ban in ban_group)

def all_banned(part, ban_group):
    # use `all` to see if all of the users matched a ban pattern.
    return all(is_banned(user, ban_group) for user in part)

def solution(user_group, ban_group):
    # apply the `all_banned` logic to each combination of users of the
    # specified size.
    return [
        part for part in combinations(user_group, len(ban_group))
        if all_banned(part, ban_group)
    ]

我希望我正确理解了预期的逻辑。如果没有,那么应该很容易修复,使用类似的技术

如果我现在理解的话,您想在candidate = []后面附加一个part,前提是所有元素都与ban组中的co-respondend-position元素匹配。但是在代码中,如果这些元素中的任何一个与它们都不匹配,那么您就是在part后面追加了candidate。 这就是为什么我要使用flag来跟踪part中的所有元素是否匹配

from itertools import combinations
def check_id(user, ban):
    for i in range(len(ban)):
        if ban[i] == '*':
            continue
        elif user[i] != ban[i]:
            return False
    return True

candidates = []
def solution(user_group, ban_group):
    for part in combinations(user_group, len(ban_group)):
        flag = True
        for i in range(len(part)):
            flag = flag and check_id(part[i], ban_group[i])
        if flag:
            candidates.append(part)
    return candidates

print(solution(["frodo", "fradi", "crodo", "abc123", "frodoc"], ["fr*d*", "abc1**"]))

在此片段中:

        for i in range(len(part)):
            if check_id(part[i], ban_group[i]) is True:
                candidates.append(part)

如果part中的任何项通过check_id,则将part附加到candidates。我认为只有当part中的所有项目都通过check_id时,您才想这样做。因此,正确的做法是:

        if all(check_id(part[i], ban_group[i]) for i in range(len(part))):
            candidates.append(part)

顺便说一句,Karl Knechtel对check_id函数的看法是正确的-这也不正确,看看check_id('frodoc', 'fr*d*')做了什么就知道了

相关问题 更多 >

    热门问题