繁体   English   中英

旋转图像列表理解

[英]rotate Image List comprehension

在解决矩阵旋转问题时,我遇到了一个解决方案。问题是将矩阵旋转90度。

def rotateImage(a):
    rows = len(a)
    cols = len(a[0])
    a=a[::-1]
    return [[m[i] for m in  a] for i in range(cols)]

有人可以帮助我将列表理解分解为常规的for循环并了解程序的流程吗

您有一个嵌套列表理解,一个外部列表理解为每次迭代创建一个新列表。

您可以通过读取forif组件从左到右作为嵌套块来解构任何列表理解。 第一个for之前的所有内容都是产生列表元素的表达式。

因此,基本结构为:

[<expression> for <targets> in <iterable> <optionally more if and for>]

始终可以使用以下命令将其转换为常规循环:

_result = []
for <targets> in <iterable>:
    <optionally more if and for blocks, add a new level each time>
        _result.append(<expression>)

我添加了_result作为所生成列表的显式名称。 请注意,每次迭代都会将<expression>的结果附加到它的后面。

您的示例分为两个列表理解。 外循环是这样的:

[[m[i] for m in  a] for i in range(cols)]
# \              /      |     \       /
#   <expression>    <targets>  <iterable>

因此[m[i] for m in a]是这里的表达式! 将其写为:

_result_outer = []
for i in range(cols):
    _result_outer.append([m[i] for m in  a])

内部列表的理解很简单:

_result_inner = []
for m in a:
    _result_inner.append(m[i])

如果将这两部分放在一起,您将获得:

_result_outer = []
for i in range(cols):
    _result_inner = []
    for m in a:
        _result_inner.append(m[i])
    _result_outer.append(_result_inner)

现在您可以看到,每次在内部循环中都使用外部循环中的i目标。 因为i遍历了列数,但是m是一行,所以这首先生成一个列表,其中包含第一列的所有值,然后是第二列,然后是第三列,依此类推。

列表理解之前的那一行使反转

a = a[::-1]

这将占用所有行,并从最后一行到第一行(向后退,步长为-1 )。 这样可以使列表理解以相反的顺序遍历行。

该代码可以清理和改进一点。 例如,从不使用rows变量,我们可以使用reversed()函数以相反的顺序遍历列表,而无需创建副本:

def rotateImage(a):
    cols = len(a[0])
    return [[m[i] for m in reversed(a)] for i in range(cols)]

转换矩阵(将列移动到行)的另一种方法是使用zip()函数,其中所有行都应用为单独的参数,并带有*<expression>调用语法:

def rotateImage(a):
    return [list(r) for r in zip(*reversed(a))]

这仍然使用列表推导,因为zip()会生成一个可迭代的对象 ,而不是列表,并且每次迭代时都会得到一个元组。 上面的列表理解将整个结果转换回列表列表。

如果您想就地执行此操作,建议您阅读Jack关于用Python旋转矩阵的出色回答。 他们对如何编码的解释是首屈一指的: 如何旋转二维数组?

a=a[::-1]只是一个反向。 列表理解为:

res = []
for i in range(cols):
    tmp = []
    for m in a:
        tmp.append(m[i])
    res.append(tmp)
return res

****编辑****

基本上,这里发生的是对于每个列索引i ,算法遍历所有行m (从最后到第一),并将m[i] (第m行中的第i个值)附加到tmp ,然后作为行附加到res 因此,每个反向列都作为一行添加到res

因此,对于像这样的矩阵:

1 2 3 4
5 6 7 8
9 1 0 4

第一次内部循环迭代将导致tmp=[9, 5, 1]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM