一行代码搞定矩阵旋转——python

在刷Leetcode的48题“Rotate Image”的时候,在网上搜了一下答案,结果被一个Python写的答案惊艳到了,人生苦短,Python是岸!

废话少说,先上代码。

题目是这样的:

You are given an n x n 2D matrix representing an image.
Rotate the image by 90 degrees (clockwise).

Follow up:
Could you do this in-place?

其中一种Python实现是这样的。

    def rotate(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: void Do not return anything, modify matrix in-place instead.
        """
        matrix[:] = map(list,zip(*matrix[::-1]))

一行代码解决这个问题。

这段代码很巧妙的运用了map和zip函数。

首先来看一下map函数。

map(function, iterable, ...)

    Apply function to every item of iterable and return a list of the results. 
    If additional iterable arguments are passed, function must take that many 
    arguments and is applied to the items from all iterables in parallel. If 
    one iterable is shorter than another it is assumed to be extended with 
    None items. If function isNone, the identity function is assumed; if there 
    are multiple arguments, map() returns a list consisting of tuples containing 
    the corresponding items from all iterables (a kind of transpose operation). 
    The iterable arguments may be a sequence or any iterable object; the result 
    is always a list.


从文档解释看,map函数的使用需要注意2点:

1、对可迭代函数'iterable'中的每一个元素应用‘function’方法,将结果作为list返回。

2、如果给出了额外的可迭代参数,则对每个可迭代参数中的元素‘并行’的应用‘function’。

上面的map(list,zip(*matrix[::-1])) 就是将zip()结果中的每个元素转化成list。


接着再看zip函数。

zip(...)
    zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)]
    
    Return a list of tuples, where each tuple contains the i-th element
    from each of the argument sequences.  The returned list is truncated
    in length to the length of the shortest argument sequence.

也就是说,zip([seql, …])接受一系列可迭代对象作为参数,将对象中对应的元素打包成一个个tuple(元组),然后返回由这些tuples组成的list(列表)。若传入参数的长度不等,则返回list的长度和参数中长度最短的对象相同。

另外,zip()配合*号操作符,可以将已经zip过的列表对象解压。这个用法配合map函数可以实现矩阵的转置。如:

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

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

>>>map(list,zip(*[[1,2,3],[4,5,6],[7,8,9]]))

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

那么,要实现矩阵的顺时针旋转,该怎么做呢?

可以曲线救国,先把矩阵上下翻转,然后在转置一下。

于是就有了上面的代码。

matrix[:] = map(list,zip(*matrix[::-1]))


那么问题又来了,如何实现逆时针旋转呢?

先把矩阵转置一下,然后在上下翻转。

matrix[:] = map(list,zip(*matrix))[::-1]

有人会问,为什么不左右翻转,再转置一下呢?

个人觉得在Python中,矩阵是以list的list存储的,简单的说,就是以行为单元,故行之间的操作要比列之间的操作方便。






参考链接:

https://my.oschina.net/zyzzy/blog/115096

http://www.cnblogs.com/BeginMan/archive/2013/03/14/2959447.html




你可能感兴趣的:(Python)