在Python中旋转二维数组

在我编写的一个程序中,出现了旋转二维数组的需要。在寻找最佳解决方案时,我发现了这一令人印象深刻的一行代码:

rotated=zip(*原始[:-1])

我现在正在我的程序中使用它,它按预期工作。但我的问题是,我不明白它是如何工作的

如果有人能解释一下所涉及的不同功能是如何达到预期效果的,我将不胜感激

这是聪明的一点

首先,如注释中所述,在Python 3中,zip()返回一个迭代器,因此需要将整个内容包含在list()中,以获得一个实际的列表,因此从2020年起,它实际上是:

列表(zip(*原件[:-1]))

以下是分类:

  • [::-1]-以相反顺序创建原始列表的浅层副本。还可以使用reversed(),这将在列表上生成一个反向迭代器,而不是实际复制列表(内存效率更高)
  • *-使原始列表中的每个子列表成为zip()的单独参数(即,解压列表)
  • zip()-从每个参数中提取一项,并从中生成一个列表(也就是元组),然后重复,直到所有子列表都用尽为止。这就是换位实际发生的地方
  • list()zip()的输出转换为列表

假设你有这个:

[[1,2,3],
[4, 5, 6],
[7, 8, 9] ]

你首先得到这个(浅拷贝,反向拷贝):

[[7,8,9],
[4, 5, 6],
[1, 2, 3] ]

接下来,将每个子列表作为参数传递给zip

zip([7,8,9]、[4,5,6]、[1,2,3])

zip()从每个参数的开头重复使用一个项,并从中生成元组,直到没有更多项为止,结果(在转换为列表后):

[(7,4,1),
(8, 5, 2), 
(9, 6, 3)]

鲍勃是你叔叔

要回答@IkeMiguel在评论中提出的关于将其旋转到另一个方向的问题,非常简单:您只需要反转进入zip的序列和结果。第一种方法可以通过删除[::-1]来实现,第二种方法可以通过在整个过程中抛出反转()来实现。由于reversed()在列表上返回一个迭代器,因此我们需要在周围放置list()以转换它。使用两个额外的list()调用将迭代器转换为实际列表。因此:

旋转=列表(反转(列表(zip(*原始)))

我们可以通过使用;“火星人的微笑”;切片而不是反转()。。。那么我们就不需要外部的列表()

rotated=list(zip(*original))[:-1]

当然,您也可以简单地顺时针旋转列表三次。:-)

发表评论