如何在列表理解中重复列表?

How do you repeat a list within a list comprehension?

我正在努力提高我的列表理解能力,寻找练习来加深我的理解。但我已经达到了一个我似乎无法绕过的地方。假设我想要一个包含范围 (1,3) 内 3 个随机数字的所有可能列表的列表,其中每个列表的总和不等于 3.

[[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 1, 1], [0, 2, 0] ...]

显然,我需要使用嵌套列表推导式来执行此操作。但我真的不确定该怎么做。据我所知,我无法将列表分配给列表理解中的变量。但是我需要那个变量来引用输出:

list7 = [[randint(0,2) for x in range(3)] for y if sum(y) != 3]

这给我一个语法错误。我试过先将内部列表分配给一个变量,但这似乎也不起作用:

y = [randint(0,2) for x in range(3)]
list7 = [y for y if sum(y) != 3]

不过,令我困惑的是“y”在这里完全没有给出错误。即使未将 randint 分配给“x”,它的行为也符合我的预期。显然这里有些我不明白的地方。所以,这是我的问题:如果我不能将它分配给理解中的变量,我如何在列表理解中重复嵌套列表?提前致谢。

正如我在评论中指出的那样,您的解决方案存在一个问题,即外部列表理解没有可迭代项。那么它如何知道要产生多少结果,或何时停止产生结果?

您的 if 子句也有问题。在您的 if 中,您执行 sum(y),我认为这意味着“对 [randint(0,2) for x in range(3)] 的结果求和”。这是倒退的,因为 if 首先执行。此外,y 是迭代器中当前项目的循环变量,而不是该项目的列表理解的结果。

您的解决方案的另一个问题是您使用的是 randint。因此,您可能会多次生成某些组合,而另一些则根本不会。这有点离题了。

我想您可能希望将类似的东西变成列表理解。

results = []
for i in range(3):
    for j in range(3):
        for k in range(3):
            if i + j + k != 3:
                results.append([i, j, k])

这是完全可行的,但答案不是嵌套列表理解,因为那是当你需要生成列表列表时,在这种情况下,只有你的外部列表需要理解,你的内部列表只有 3容器中的数字。它可以很容易地成为一个元组。

最好从您最终想要得到的列表的列表的角度来考虑这个问题。这意味着您需要生成一个列表的东西,其中包含其他列表。

所以你想生成这 3 位数字,检查它们是否加起来等于 3,如果不是,它们就是作为列表添加到结果中的项目之一。您可以利用 python 中的列表解析支持多个迭代器这一事实,来实现与嵌套 for 循环相同的功能。

results = [
    [i, j, k] 
    for i in range(3) for j in range(3) for k in range(3)
    if i + j + k != 3
]

查看官方文档以获得更多有用的示例:http://docs.python.org/2/tutorial/datastructures.html#list-comprehensions


编辑:

我想到你想做的是这样的:

results = [
    item for item in [
        [i, j, k] 
        for i in range(3) for j in range(3) for k in range(3)
    ]
    if sum(item) != 3
]

这看起来更像你的代码。这在结果方面是等效的,但性能可能要低得多(在进程和内存方面),因为在这个例子中,您将所有 [i, j, k] 可能性构建到一个列表中,然后将它们过滤到那些加起来不等于 3 的。最好根本就没有构造过这些列表。对于这个简单的例子,它没有什么区别,但如果 [x, y, z] 构建起来很昂贵,或者每个项目使用大量内存,它可能很重要。