2024-05-16 20:33:06 发布
网友
在我编写的一个程序中,需要旋转二维数组。在寻找最佳解决方案的过程中,我发现了一条令人印象深刻的直线:
rotated = zip(*original[::-1])
我正在我的程序中使用它,它按预期工作。但我的问题是,我不明白它是如何工作的。
如果有人能解释一下所涉及的不同功能是如何达到预期效果的,我将不胜感激。
这有三个部分:
请考虑以下二维列表:
original = [[1, 2], [3, 4]]
让我们一步一步地分解它:
>>> original[::-1] # elements of original are reversed [[3, 4], [1, 2]]
使用argument unpacking将此列表传递到zip()中,因此zip调用最终等同于:
zip()
zip
zip([3, 4], [1, 2]) # ^ ^----column 2 # |-------column 1 # returns [(3, 1), (4, 2)], which is a original rotated clockwise
希望这些注释清楚地说明了zip的作用,它将根据索引对每个输入iterable中的元素进行分组,或者换句话说,它将列分组。
真聪明。下面是故障:
[::-1]
reversed()
*
所以假设你有这个:
[ [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()来实现。由于reversed()返回列表上的迭代器,我们需要将list()放在周围以转换它。所以:
list()
rotated = list(zip(*reversed(original)))
当然,您也可以将列表顺时针旋转三次。:-)
这有三个部分:
请考虑以下二维列表:
让我们一步一步地分解它:
使用argument unpacking将此列表传递到
zip()
中,因此zip
调用最终等同于:希望这些注释清楚地说明了
zip
的作用,它将根据索引对每个输入iterable中的元素进行分组,或者换句话说,它将列分组。真聪明。下面是故障:
[::-1]
-按相反顺序生成原始列表的浅层副本。也可以使用reversed()
,这将在列表上生成一个反向迭代器,而不是实际复制列表(更节省内存)。*
-使原始列表中的每个子列表成为zip()
的单独参数(即,解压缩列表)zip()
-从每个参数中提取一个项,并从中生成一个列表(一个元组),然后重复,直到所有子列表都用完为止。这就是真正发生换位的地方。所以假设你有这个:
你首先得到这个(浅的,反拷贝):
接下来,每个子列表都作为参数传递给
zip
:zip()
从每个参数的开头重复使用一个项并从中生成一个元组,直到没有更多项为止,结果是:鲍勃是你叔叔。
要在注释中回答@IkeMiguel关于将其旋转到另一个方向的问题,非常简单:您只需要反转进入
zip
的序列和结果。第一个可以通过删除[::-1]
来实现,第二个可以通过在整个对象周围抛出reversed()
来实现。由于reversed()
返回列表上的迭代器,我们需要将list()
放在周围以转换它。所以:当然,您也可以将列表顺时针旋转三次。:-)
相关问题 更多 >
编程相关推荐