【问题标题】:Trying to wrap my head around variable input arguments in python functions试图围绕python函数中的可变输入参数
【发布时间】:2018-12-14 07:19:00
【问题描述】:

首先我要说这是我正在处理的代码挑战,其参数如下。

所以,首先,编写一个名为 Covers 的函数,它接受一个参数,即一组主题。让函数返回来自 COURSES 的课程列表,其中提供的集合和课程的值(也是一个集合)重叠。例如,cover({"Python"}) 将返回 ["Python Basics"]。

这是我从中提取的包含课程主题嵌套集的字典。

COURSES = {
"Python Basics": {"Python", "functions", "variables",
                  "booleans", "integers", "floats",
                  "arrays", "strings", "exceptions",
                  "conditions", "input", "loops"},
"Java Basics": {"Java", "strings", "variables",
                "input", "exceptions", "integers",
                "booleans", "loops"},
"PHP Basics": {"PHP", "variables", "conditions",
               "integers", "floats", "strings",
               "booleans", "HTML"},
"Ruby Basics": {"Ruby", "strings", "floats",
                "integers", "conditions",
                "functions", "input"}}

现在,搜索字典的集合是对 for 循环的一种非常严格的向前使用,但挑战听起来像是要我创建一个新的课程名称集合,其主题与参数(的)输入相匹配,并输出结果作为一个列表。

def covers(topics):
    hold_set = set()
    for key in COURSES.keys():
        if topics in COURSES[key]:
            result = key
            hold_set.add(result)
        else:
            continue
    conversion = list(hold_set)
    return conversion

现在我的第一个问题是接受可变数量的参数,我对 *args / **kwargs 不是很熟悉,所以我在这里使用它们的尝试大多只是导致 print 函数给了我空列表。另一个是创建一个额外的不必要的集合来与在字典中搜索子集后创建的新集合进行比较,这似乎是多余的,因为 hold_set 已经包含名称并将它们与我假设的 .intersection() 进行比较,然后再转换列表中的结果只是通过更多的工作来获得相同的结果。

但是我离题了,现在我假设这里的主要问题是函数无法接受关于主题搜索参数的可变数量的参数(因为在提交挑战时,它说“没有从covers."),所以如果有人能阐明我如何使这成为可能,那将不胜感激,因为几天后我的大脑开始糊涂,我开始阅读有关计算机科学其他领域的文章解压。

【问题讨论】:

    标签: python-3.x dictionary set args keyword-argument


    【解决方案1】:

    如果你想使用多个参数,你可以试试这个:

    def covers(*args):
    
        mydict = dict()
    
        for arg in args:
            mylist = list()
    
            for k, v in COURSES.items():
                if arg in v:
                    mylist.append(k)
    
            mydict[arg] = mylist
    
        return mydict
    

    使用 dict 和列表推导,您可以缩短它:

    def covers(*args):
        return {arg: [k for k, v in COURSES.items() if arg in v] for arg in args}
    

    这会生成一个字典,其中包含您提供的每个字符串的条目。条目的值是一个包含所有匹配课程的列表。所以如果你这样称呼它:

    covers('variables', 'Python')
    

    你得到以下字典:

    {'variables': ['PHP Basics', 'Java Basics', 'Python Basics'], 'Python': ['Python Basics']}
    

    关于多个参数的问题: *args 捕获列表中未在函数定义中显式声明的所有位置参数, **kwargs 类似地捕获字典中的所有关键字参数。因此,通过仅将 *args 定义为函数参数,来自函数调用的所有参数都存储为列表,可以像往常一样进行迭代。

    【讨论】:

    • 这实际上是对 *args 和 **kwargs 的更好解释,比我在挖掘文档和各种教程中找到的要好得多,所以谢谢你。它绝对可以帮助我了解现在和将来如何更好地利用它们。我还有一个问题是关于让函数接受来自字符串以外的输入的。那可能吗?如果我想调用 cover({'variables', 'Python'}) 或者我会怎么做?现在,使用我的示例和您的示例返回列表,列表最终返回为空。
    • @GiantsBane:不客气。我不确定我是否正确理解了您的要求。所以你想给一个包含函数输入的集合?
    • 是的,我相信这就是他们想要的。例如,covers({"Python"}) 将返回 ["Python Basics"]。但是当我尝试使用一个集合作为输入时,我只会得到空白列表。如果我推测一下,我会想象使用一组输入而不是单个参数的价值将是单次搜索与多次搜索,从而使事情变得更快?
    • 如果是这种情况,你可以定义你的集合,然后通过covers(*myset)调用函数。这将解包集合并将它们作为未命名的位置参数提供给函数。因此,它们像之前的示例一样存储在 args 变量中。
    • 感谢 Doc,在获得更多信息后,我意识到我只是在思考这个问题,*args 是不必要的(尽管学习如何更好地利用它很好),并且挑战失败了,因为我没有使用交集运算符来比较事物(即使从未明确要求它,所以,这很头疼)。感谢您对我试图理解的问题的建议和见解。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-14
    • 2014-05-22
    • 2022-12-07
    • 2019-05-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多