我有一个for循环来创建列表,可以改为使用列表理解吗? [英] I have a for loop to create a list, can I use a list comprehension instead?

查看:71
本文介绍了我有一个for循环来创建列表,可以改为使用列表理解吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Let's have a list of values and an arbitrary integer number.

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

我想将值与n数字连续分组.

I'd like to group the values with n numbers in a row.

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

Let us suppose n=9, that is 9 numbers will be in a row.

结果应该是这样的:

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

我可以这样:

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

但是有人怀疑可以在这里使用列表理解. 您能帮我了解如何完成吗?

But there is a suspicion that list comprehension can be used here. Could you help me understand how can it be done?

推荐答案

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

Just move the expression in the list.append() call to the front, and add the for loop:

grouped_values = [values[i:i + 9] for i in range(rows_number)]

请注意,这不会将输入列表切成连续的 元素块.它会产生一个滑动窗口;您先切片values[0:9],然后切片values[1:10],依此类推.它将在输入数据上生成窗口,每个窗口的长度为9,其中8个元素与前一个窗口重叠.要生成连续的长度为9的,请使用range(0, len(values), n)作为范围,而无需计算rows_number:

Note that this does not slice up your input list into chunks of consecutive elements. It produces a sliding window; you slice values[0:9] then values[1:10], etc. It produces windows onto the input data, each of length 9, with 8 elements overlapping with the previous window. To produce consecutive chunks of length 9, use range(0, len(values), n) as the range, no need to calculate rows_number:

grouped_values = [values[i:i + n] for i in range(0, len(values), n)]

只要您看到这样的模式:

Whenever you see a pattern like this:

<list_name> = []

for <targets> in <iterable>:
    <list_name>.append(<expression>)

<expression>不引用<list_name>的地方,您可以轻松地将其转换为

where <expression> does not reference <list_name>, you can trivially turn that into

<list_name> = [<expression> for <targets> in <iterable>]

这里唯一的区别是,只有在执行整个列表理解之后的之后,才设置list_name.您不能从列表理解中引用正在构建的列表.

The only difference here is that list_name is not set until after the whole list comprehension has been executed. You can't reference the list being built from inside the list comprehension.

有时候,您需要在循环主体中移动其他代码,以将最终的<expression>值生成单个表达式,然后再到达上述模式.

Sometimes you need to move additional code in the loop body that produces that final <expression> value into a single expression before you arrive at the above pattern.

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

Note that it doesn't matter here that <expression> itself produces list objects; they can be entirely new list comprehensions or any other valid Python expression.

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

When there are more for loops or if statements with added nested levels, then list those added for loops and if statements from left-to-right in the resulting list comprehension; for example, the pattern

<list_name> = []

for <targets1> in <iterable1>:
    if <test_expression>:
        for <targets2> in <iterable2>:        
            <list_name>.append(<expression>)

成为

<list_name> = [
    <expression>
    for <targets> in <iterable>
    if <test_expression>
    for <targets2> in <iterable2>
]

这篇关于我有一个for循环来创建列表,可以改为使用列表理解吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆