在我编写的一个程序中,出现了旋转二维数组的需要。在寻找最佳解决方案时,我发现了这一令人印象深刻的一行代码:
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]
当然,您也可以简单地顺时针旋转列表三次。:-)