我有一个for循环来创建一个列表,我可以使用列表理解吗?

Mic*_*ael 4 python list-comprehension

让我们有一个值列表和一个任意整数.

values = ['5', '3', '.', '.', '7', '.', '.', '.', '.', '6', '.', '.', '1', '9', '5', '.', '.', '.', '.', '9', '8', '.', '.', '.', '.', '6', '.', '8', '.', '.', '.', '6', '.', '.', '.', '3', '4', '.', '.', '8', '.', '3', '.', '.', '1', '7', '.', '.', '.', '2', '.', '.', '.', '6', '.', '6', '.', '.', '.', '.', '2', '8', '.', '.', '.', '.', '4', '1', '9', '.', '.', '5', '.', '.', '.', '.', '8', '.', '.', '7', '9']

n = 9
Run Code Online (Sandbox Code Playgroud)

我想将值与n行中的数字分组.

让我们假设n=9,即9个数字将连续存在.

结果应该是这样的:

grouped_values = [
     ['5', '3', '.', '.', '7', '.', '.', '.', '.'],
     ['6', '.', '.', '1', '9', '5', '.', '.', '.'],
     ['.', '9', '8', '.', '.', '.', '.', '6', '.'],
     ['8', '.', '.', '.', '6', '.', '.', '.', '3'],
     ['4', '.', '.', '8', '.', '3', '.', '.', '1'],
     ['7', '.', '.', '.', '2', '.', '.', '.', '6'],
     ['.', '6', '.', '.', '.', '.', '2', '8', '.'],
     ['.', '.', '.', '4', '1', '9', '.', '.', '5'],
     ['.', '.', '.', '.', '8', '.', '.', '7', '9']]
Run Code Online (Sandbox Code Playgroud)

我可以这样做:

def group(values, n):
   rows_number = int(len(values)/n) # Simplified. Exceptions will be caught.
   grouped_values = []

   for i in range(0, rows_number):
      grouped_values.append(values[i:i+9])
Run Code Online (Sandbox Code Playgroud)

但有人怀疑列表理解可以在这里使用.你能帮我理解怎么做?

Mar*_*ers 11

只需将list.append()调用中的表达式移到前面,然后添加for循环:

grouped_values = [values[i:i + 9] for i in range(rows_number)]
Run Code Online (Sandbox Code Playgroud)

请注意,这并没有分好你的输入列表分成大块连续的元素.它产生一个滑动窗口 ; values[0:9]然后切片values[1:10]等.它在输入数据上产生窗口,每个长度为9,其中8个元素与前一个窗口重叠.要生成长度为9的连续,请使用range(0, len(values), n)范围,无需计算rows_number:

grouped_values = [values[i:i + n] for i in range(0, len(values), n)]
Run Code Online (Sandbox Code Playgroud)

每当你看到这样的模式时:

<list_name> = []

for <targets> in <iterable>:
    <list_name>.append(<expression>)
Run Code Online (Sandbox Code Playgroud)

在哪里<expression>不参考<list_name>,你可以轻而易举地把它变成

<list_name> = [<expression> for <targets> in <iterable>]
Run Code Online (Sandbox Code Playgroud)

这里唯一的区别是list_name直到整个列表理解被执行后才设置.您无法从列表推导中引用正在构建的列表.

有时您需要<expression>在到达上述模式之前将循环体中的其他代码移动到单个表达式中.

注意,这里它<expression>本身产生列表对象并不重要; 它们可以是全新的列表推导或任何其他有效的Python表达式.

当有更多for循环或if语句添加了嵌套级别时,在结果列表理解中从左到右列出这些添加的for循环和if语句; 例如,模式

<list_name> = []

for <targets1> in <iterable1>:
    if <test_expression>:
        for <targets2> in <iterable2>:        
            <list_name>.append(<expression>)
Run Code Online (Sandbox Code Playgroud)

<list_name> = [
    <expression>
    for <targets> in <iterable>
    if <test_expression>
    for <targets2> in <iterable2>
]
Run Code Online (Sandbox Code Playgroud)