【问题标题】:How to expand this nested list comprehension in Python如何在 Python 中扩展这个嵌套列表理解
【发布时间】:2018-10-15 23:16:39
【问题描述】:

考虑以下函数:

它将列表列表作为输入,并从每个列表中查找元素的所有组合。

def product(llist):
    result = [[]]

    for lst in llist:
        result = [x + [y] for x in result for y in lst]

    return result

例如:

product([[1,2], [3], [4,5]])

会返回:

[[1, 3, 4], [1, 3, 5], [2, 3, 4], [2, 3, 5]]

我正在尝试了解此功能的工作原理,因此尝试扩展列表理解。

试试看:

def product2(llist):
    result = [[]]
    for lst in llist:
        for x in result:
            result = []
            for y in lst:
                result.append(x+[y])

    return result

这并没有给我正确的结果,它返回:

[[2, 3, 4], [2, 3, 5]]

根据product2 的定义,我理解这个不正确的结果。但是我无法扩展原来的 product 函数来了解它是如何工作的。

有人可以详细说明product 函数中的嵌套列表理解吗?

【问题讨论】:

    标签: python python-3.x list list-comprehension nested-loops


    【解决方案1】:

    列表推导为lst 中的每个元素创建一个新列表,并通过将这个小的单个元素列表与result 中已有的所有列表相结合来创建更多新列表。

    因此,例如,如果 result = [ [1, 2], [3, 4] ]lst = [10, 11],则新结果将是 [[1, 2, 10], [1, 2, 11], [3, 4, 10], [3, 4, 11]]

    它正在为llist 中的每个lst 执行此操作:

    def product2(llist):
        result = [[]]
        for lst in llist:
            new_result = [] # let's manually build out new result
            for existing in result:            
                for element in lst:
                    new_result.append(existing + [element])
            result = new_result # update result for next lst
        return result
    

    【讨论】:

    • 非常好,我错过了最后一点
    • @vash_the_stampede 谢谢。很容易忽略它实际上是 3 个循环。
    【解决方案2】:

    打印result 的部分值会很有帮助,如下所示:

    def product(llist):
        result = [[]]
    
        for lst in llist:
            result = [x + [y] for x in result for y in lst]
            print(result)
    
        return result
    

    首先results的innnerlist是空的,所以它会为传入的第一个inner list中的每个元素创建一个新的inner list:

    [[1], [2]]
    

    然后在第二次传递中,结果中的每个内部列表将被其自身加上作为参数传递的第二个内部列表中的每个元素替换:

    [[1, 3], [2, 3]]
    

    然后,当您有一个包含多个元素的内部参数列表时,它将在结果中复制当前现有的内部列表

    [[1, 3, 4], [1, 3, 5], [2, 3, 4], [2, 3, 5]]
    

    之所以会这样,是因为在一次通过列表理解时,相关列表将不会被更新。它只会在理解结束时更新。

    另一种你可以看到它的方式就像一个网格:

    ------------------
    |    |  1  |  2  |
    ------------------
    | [] | [1] | [2] |
    ------------------
    
    result = [[1],[2]]
    
    ---------------
    |     |   3   |
    ---------------
    | [1] | [1,3] |
    ---------------
    | [2] | [2,3] |
    ---------------
    
    result = [[1,3],[2,3]]
    
    -----------------------------
    |       |    4    |    5    |
    -----------------------------
    | [1,3] | [1,3,4] | [1,3,5] |
    -----------------------------
    | [2,3] | [2,3,4] | [2,3,5] |
    -----------------------------
    
    result = [[1,3,4],[2,3,4],[1,3,5],[2,3,5]]
    

    考虑到这一点,没有理解的版本将需要一个临时变量来保存更新的值:

    def product2(llist):
        result = [[]]
        for lst in llist:
            temp_res = []
            for x in result:
                for y in lst:
                    temp_res.append(x+[y])
            result = temp_res
    
        return result
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-28
      • 2015-06-24
      相关资源
      最近更新 更多