如何在 Python 中扩展此嵌套列表理解

How to expand this nested list comprehension in Python

考虑以下函数:

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

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]])

会 return:

[[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

这没有给我正确的结果,它 returns:

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

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

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

列表理解正在为 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

打印 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的内层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