无法理解 for 循环的变量切片

Posted

技术标签:

【中文标题】无法理解 for 循环的变量切片【英文标题】:Unable to understand slices of variable of for loop 【发布时间】:2020-10-05 13:25:21 【问题描述】:

最近在Python "Stars and Bars"找到了一段Paul Panzer发的python代码(最佳答案)

import itertools
bars = [0, 0, 0, 0, 0, 8]
result = [[bars[j+1] - bars[j] - 1 for j in range(5)] for bars[1:-1] in itertools.combinations(range(1, 8), 4)]

我无法理解 for 循环中变量 bars[1:-1] 的片段。请帮忙。

bars 和循环中可迭代对象的成员是什么关系?

【问题讨论】:

请解释清楚“条与循环中可迭代对象的成员之间的关系是什么?” 在我对python循环的理解中,for关键字后面的变量将在迭代期间分配给可迭代对象的每个成员。我的问题是已经定义的变量bars 和循环变量的关系。 【参考方案1】:

在表达式中:

for foo in itertools.combinations(range(1, 8), 4)

itertools.combinations(range(1, 8), 4) 正在产生 4 个项目的序列,这些项目被分配给变量 foo。如果您只是在循环中打印foo,您可以看到这一点:

>>> for foo in itertools.combinations(range(1, 8), 4):
...     print(foo)
...
(1, 2, 3, 4)
(1, 2, 3, 5)
(1, 2, 3, 6)
(1, 2, 3, 7)
(1, 2, 4, 5)
(1, 2, 4, 6)
(1, 2, 4, 7)
(1, 2, 5, 6)
(1, 2, 5, 7)
(1, 2, 6, 7)
(1, 3, 4, 5)
(1, 3, 4, 6)
(1, 3, 4, 7)
(1, 3, 5, 6)
(1, 3, 5, 7)
(1, 3, 6, 7)
(1, 4, 5, 6)
(1, 4, 5, 7)
(1, 4, 6, 7)
(1, 5, 6, 7)
(2, 3, 4, 5)
(2, 3, 4, 6)
(2, 3, 4, 7)
(2, 3, 5, 6)
(2, 3, 5, 7)
(2, 3, 6, 7)
(2, 4, 5, 6)
(2, 4, 5, 7)
(2, 4, 6, 7)
(2, 5, 6, 7)
(3, 4, 5, 6)
(3, 4, 5, 7)
(3, 4, 6, 7)
(3, 5, 6, 7)
(4, 5, 6, 7)

如果您将 foo 替换为 4 个元素长的列表切片,则这 4 个元素将被分配给该切片:

>>> bars = [0, 0, 0, 0, 0, 8]
>>> for bars[1:-1] in itertools.combinations(range(1, 8), 4):
...     print(bars)
...
[0, 1, 2, 3, 4, 8]
[0, 1, 2, 3, 5, 8]
[0, 1, 2, 3, 6, 8]
[0, 1, 2, 3, 7, 8]
[0, 1, 2, 4, 5, 8]
[0, 1, 2, 4, 6, 8]
[0, 1, 2, 4, 7, 8]
[0, 1, 2, 5, 6, 8]
[0, 1, 2, 5, 7, 8]
[0, 1, 2, 6, 7, 8]
[0, 1, 3, 4, 5, 8]
[0, 1, 3, 4, 6, 8]
[0, 1, 3, 4, 7, 8]
[0, 1, 3, 5, 6, 8]
[0, 1, 3, 5, 7, 8]
[0, 1, 3, 6, 7, 8]
[0, 1, 4, 5, 6, 8]
[0, 1, 4, 5, 7, 8]
[0, 1, 4, 6, 7, 8]
[0, 1, 5, 6, 7, 8]
[0, 2, 3, 4, 5, 8]
[0, 2, 3, 4, 6, 8]
[0, 2, 3, 4, 7, 8]
[0, 2, 3, 5, 6, 8]
[0, 2, 3, 5, 7, 8]
[0, 2, 3, 6, 7, 8]
[0, 2, 4, 5, 6, 8]
[0, 2, 4, 5, 7, 8]
[0, 2, 4, 6, 7, 8]
[0, 2, 5, 6, 7, 8]
[0, 3, 4, 5, 6, 8]
[0, 3, 4, 5, 7, 8]
[0, 3, 4, 6, 7, 8]
[0, 3, 5, 6, 7, 8]
[0, 4, 5, 6, 7, 8]

相同的 4 个元素,但现在它们被分配到 bars 的中间,正如切片表达式 bars[1:-1] 所引用的那样。

在您理解的上下文中,bars 在通过外循环时将具有这些值。内部理解生成另一个列表,该列表基于该外部循环中bars 的值。

【讨论】:

谢谢,我可以从您提供的输出中隐约理解该过程。但是,是否有任何文件可能与此相关? 而且我还发现如果对第二段代码,即[bars for bars[1:-1] in itertools.combinations(range(1, 8), 4)]使用行压缩,输出将是一个包含35个重复[0, 4, 5, 6, 7, 8]的列​​表。你能给我解释一下吗?【参考方案2】:

bars[1:-1] 基本上表示从索引1-1 的所有列表项,其中-1 表示最后一个索引。

所以如果bars = [1,2,3,4,5]bars[1:-1] = [2,3,4]

【讨论】:

以上是关于无法理解 for 循环的变量切片的主要内容,如果未能解决你的问题,请参考以下文章

python:使用列表切片作为for循环的目标

无法理解此代码中使用的 for 循环

Python中对于多个for循环和变量的列表理解

如何理解Golang中的range语句

C语言中for循环怎么理解?

在 Python 中将列表理解转换为 For 循环