如何在列表理解中重复列表?
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]
构建起来很昂贵,或者每个项目使用大量内存,它可能很重要。
我正在努力提高我的列表理解能力,寻找练习来加深我的理解。但我已经达到了一个我似乎无法绕过的地方。假设我想要一个包含范围 (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]
构建起来很昂贵,或者每个项目使用大量内存,它可能很重要。