python3中二維List數據的三種處理方法及比較

python3中二維List數據的三種處理方法及比較

標籤: python 矩陣 算法python


[TOC]git

問題引入

這幾天在處理一個棋盤狀態數據,須要對棋盤狀態狀態是否爲「同一個狀態」,這裏就須要對棋盤狀態進行旋轉,左右翻轉等操做。一個棋盤總共能夠旋轉:0度,90度,180度,270度4種;每種旋轉後還能夠左右翻轉2種,總共有4x2=8種狀態。爲了方便,須要先用python把這8種狀態表示出來,因而引出了題目的問題:在python裏如何對矩陣進行變化,這裏的變化指旋轉和左右翻轉等。 這裏使用的版本是python3.6算法

原始數據

爲了簡便,使用一個最簡單的數據來模擬:一個2X2的棋盤用List來保存下數據code

lstDat = [
    [1,2],
    [3,4],
]

指望的最終結果有8個,分別是這樣的: 其中1,3,5,7 分別是旋轉0度,90度,180度,270度; 二、四、六、8 分鐘是一、三、五、7進行左右翻轉獲得的結果。orm

NO.1
1 2
3 4

No.2: 
2 1
4 3

No.3:
2 4
1 3

No.4
4 2 
3 1

No.5
4 3 
2 1

No.6
3 4
1 2

No.7
1 3
2 4

N0.8
3 1 
4 2

對於矩陣的處理有不少,但在這裏只須要用到兩種:ip

  1. 旋轉90度(順時針,逆時針均可以)
  2. 左右翻轉

因此最終問題轉變爲如何實現對List表示的二維矩陣進行上述的兩種操做。get

使用列表生成式

列表生成式就是使用如下的方式來遍歷生成一個新的表列: [ 變量表達式 for 變量 in 表達式 ] 固然是循環是能夠嵌套的。源碼

#---------------------------------------
## 使用列表生成式
def listGen (lstDat):

    #transpose
    print('-'* 30)
    print ('轉置矩陣:')
    tp = [[row[i] for row in lstDat ] for i in range(len(lstDat[0]))]
    for item in tp: print (item)

    print('-'* 30)
    #逆時針轉90度
    print ('逆時針轉90度:')
    rt90 = [[row[i] for row in lstDat ] for i in range(len(lstDat[0])-1,-1,-1)  ]
    for item in rt90: print (item)

    print('-'* 30)
    #順時針轉90度
    print ('順時針轉90度:')
    rt90 = [[lstDat[j][i] for j in range(len(lstDat)-1,-1,-1) ] for i in range(len(lstDat[0]))]
    for item in rt90: print (item)

    print('-'* 30)
    print ('左右翻轉:')
    flip = [[row[i] for i in range(len(row)-1,-1,-1) ] for row in lstDat]
    for item in flip: print (item)

運行結果:it

---------- python36 ----------
原始數據:
[1, 2]
[3, 4]
使用列表生成器:
------------------------------
轉置矩陣:
[1, 3]
[2, 4]
------------------------------
逆時針轉90度:
[2, 4]
[1, 3]
------------------------------
順時針轉90度:
[3, 1]
[4, 2]
------------------------------
左右翻轉:
[2, 1]
[4, 3]

輸出完成 (耗時: 0 秒)

使用map + zip

使用map能夠方便對矩陣進行轉置,也就是把(行,列)變成 (列,行)的方式。對於旋轉是有直接的方法的,可是左右翻轉沒有,因此須要先逆時針旋轉90度,再進行轉置。ast

def mapzip (lstDat):
    print('-'* 30)
    print ('轉置矩陣:')
    matrix = lstDat.copy()
    matrix[:] = map(list,zip(*matrix))
    for item in matrix: print (item)


    #順時針轉90度
    print ('順時針轉90度:')
    matrix = lstDat.copy()
    matrix[:] = map(list,zip(*matrix[::-1]))
    for item in matrix: print (item)

    #逆時針轉90度
    print ('逆時針轉90度:')
    matrix = lstDat.copy()
    matrix[:] = map(list,zip(*matrix))
    matrix[:] = matrix[::-1]
    for item in matrix: print (item)
    
    #左右翻轉
    print ('左右翻轉:')
    matrix = lstDat.copy()
    matrix[:] = map(list,zip(*matrix))
    matrix[:] = matrix[::-1]
    matrix[:] = map(list,zip(*matrix))
    for item in matrix: print (item)

運行結果:

---------- python36 ----------
原始數據:
[1, 2]
[3, 4]
==============================
使用Map+Zip:
------------------------------
轉置矩陣:
[1, 3]
[2, 4]
順時針轉90度:
[3, 1]
[4, 2]
逆時針轉90度:
[2, 4]
[1, 3]
左右翻轉:
[2, 1]
[4, 3]

輸出完成 (耗時: 0 秒)

使用numpy

最後一種方法就是直接用現成的庫了,numpy提供了豐富的方法,這裏只須要用到兩個就夠了。與map的方式相同,對於旋轉是有直接的方法的,可是左右翻轉沒有,因此也須要先逆時針旋轉90度,再進行轉置。

import numpy

## 使用numpy
def usenumpy (lstDat):
    nd = numpy.array(lstDat)

    #逆時針轉90度: 
    print ('逆時針轉90度:')
    nd1 = numpy.rot90(nd)
    print (nd1)


    print ('順時針轉90度:')
    nd1 = numpy.rot90(nd,k = -1)
    print (nd1)

    print ('左右翻轉:')
    nd1 = numpy.rot90(nd)
    nd1 = numpy.transpose(nd1)
    print (nd1)

運行結果

---------- python36 ----------
原始數據:
[1, 2]
[3, 4]
==============================
使用numpy:
逆時針轉90度:
[[2 4]
 [1 3]]
順時針轉90度:
[[3 1]
 [4 2]]
左右翻轉:
[[2 1]
 [4 3]]

輸出完成 (耗時: 0 秒)

獲得結果

研究了那麼多種旋轉,左右翻轉的方式,最終仍是爲了獲得8種狀態,這裏就用numpy方式來調用實現。
import numpy

## 輸出全部狀態
def getstatus (lstDat):    
    nd = numpy.array(lstDat)
    index = 0

    for i  in range (4) :
        index +=1
        print('-'* 10 + str(index) + '-' * 10)
        print (nd)
        # 
        #print (','.join([str(y) for x in nd.tolist() for y in x]))

        index +=1
        print('-'* 10 + str(index) + '-' * 10)
        nd2 = numpy.rot90(nd)  #,k = -1,axes=(1, 0))
        nd2 = numpy.transpose(nd2)
        print (nd2)
        #print (','.join([str(y) for x in nd2.tolist() for y in x]))
        nd = numpy.rot90(nd)

運行結果:

---------- python36 ----------
原始數據:
[1, 2]
[3, 4]
==============================
輸出全部狀態:
----------1----------
[[1 2]
 [3 4]]
----------2----------
[[2 1]
 [4 3]]
----------3----------
[[2 4]
 [1 3]]
----------4----------
[[4 2]
 [3 1]]
----------5----------
[[4 3]
 [2 1]]
----------6----------
[[3 4]
 [1 2]]
----------7----------
[[3 1]
 [4 2]]
----------8----------
[[1 3]
 [2 4]]

輸出完成 (耗時: 0 秒)

分析對比

三種思路的對比: 1.列表生成器。感受這個比較傳統,仍是老思路,一個個去循環。做爲練手能夠用用。 2. 使用map 具備py的新思惟,語句也比較簡潔,建議要熟悉這種方式。 3. 使用numpy。 若是是大規模的數據,涉及到大量計算,好比ML,DL之類,仍是直接用庫吧。

完整源碼

最後附上完整的代碼: 完整源碼

相關文章
相關標籤/搜索