【问题标题】:Using list comprehension to create a list of lists in a recursive function使用列表推导在递归函数中创建列表列表
【发布时间】:2016-10-05 23:46:40
【问题描述】:

我正在试验递归函数。我的目标是制作:

一个函数combo,它生成所有加起来为n的非递增序列

一些示例输入/输出:

>>> print (combo(3))
[[3], [2, 1], [1, 1, 1]]
>>> print (combo(4))
[[4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]]
>>> print (combo(5))
[[5], [4, 1], [3, 2], [3, 1, 1], [2, 2, 1], [2, 1, 1, 1], [1, 1, 1, 1, 1]]

经过大量试验和错误,我想出了以下功能,它完全符合我的要求:

def combo(n, limit=None):
    if not limit:
        limit = n
    # return [ LIST COMPREHENSION HERE ]
    res = []
    for i in range(limit, 0, -1):
        if i == n:
            res.append([i])
        else:
            res.extend([i] + x for x in combo(n - i, min(n - i, i)))
    return res

我的问题:有没有办法(pythonic 与否)使用单个列表理解返回相同的结果,而不附加和扩展res

以下是我尝试过的两件事,以及它们的错误结果:

return [[i] if i == n else [[i] + x for x in combo(n - i, min(n - i, i))] for i in range(limit, 0, -1)]
# lists get deeper: [[4], [[3, 1]], [[2, 2], [2, [1, 1]]], [[1, [1, [1, 1]]]]]

return [[i if i == n else ([i] + x for x in combo(n - i, min(n - i, i))) for i in range(limit, 0, -1)]]
# parentheses interpreted as generator: [[4, <generator object combo.<locals>.<listcomp>.<genexpr> at 0x01D84E40>, etc.]]

我意识到答案可能很丑陋,但我已经花了足够的时间尝试,我只是想知道它是否可能

【问题讨论】:

    标签: python recursion list-comprehension


    【解决方案1】:

    extending 转换为 appending,这样更容易理解如何转换:

    res = []
    for i in range(limit, 0, -1):
        if i == n:
            res.append([i])
        else:
            # this is the generator expression pulled out of the res.extend() call
            for x in combo(n - i, min(n - i, i)):
                res.append([i] + x)
    

    您现在可以将 i == n 案例移动到另一个分支(在此处使用帮助程序 items 变量以提高可读性):

    res = []
    for i in range(limit, 0, -1):
        items = [[]] if i == n else combo(n - i, min(n - i, i))
        for x in items:
            res.append([i] + x)
    

    如果i == n,这将导致循环迭代一次并产生一个空列表,因此您有效地得到res.append([i])

    然后可以轻松地将其转换为列表解析(将 items 内联到 for 循环中):

    return [
        [i] + x
        for i in range(limit, 0, -1)
        for x in ([[]] if i == n else combo(n - i, min(n - i, i)))]
    

    你是否应该是另一回事;这很难阅读。

    【讨论】:

    • 适用于您的最新编辑(括号)。非常感谢您的周到回复!
    • @brianpck: 是的,我对此感到惊讶,因为conditional expression 是 Python 语法中 expression 规则的最顶层组件,它是 expression_list rule 的一部分 @987654323 @。我将进一步了解为什么这是一个问题。
    • 在不太了解语法规则的情况下,似乎if 被假定为条件列表理解语法的一部分,例如[i for i in x if i == 1]
    • @brianpck:是的,这也是我得出的结论 :-D 我的错误在于for 循环语法,而不是comprehension grammar
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-17
    • 1970-01-01
    • 2017-07-08
    • 2017-02-17
    • 1970-01-01
    • 2011-07-24
    相关资源
    最近更新 更多