python3中二维List数据的三种处理方法及比较

本文介绍在Python中使用列表生成式、map+zip和numpy库对二维List数据进行旋转和翻转的方法,包括顺时针、逆时针旋转90度及左右翻转,适用于棋盘状态数据处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

python3中二维List数据的三种处理方法及比较

标签: python 矩阵 算法


[TOC]

问题引入

这几天在处理一个棋盘状态数据,需要对棋盘状态状态是否为“同一个状态”,这里就需要对棋盘状态进行旋转,左右翻转等操作。一个棋盘总共可以旋转:0度,90度,180度,270度4种;每种旋转后还可以左右翻转2种,总共有4x2=8种状态。为了方便,需要先用python把这8种状态表示出来,于是引出了题目的问题:在python里如何对矩阵进行变化,这里的变化指旋转和左右翻转等。 这里使用的版本是python3.6

原始数据

为了简便,使用一个最简单的数据来模拟:一个2X2的棋盘用List来保存下数据

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

期望的最终结果有8个,分别是这样的: 其中1,3,5,7 分别是旋转0度,90度,180度,270度; 2、4、6、8 分钟是1、3、5、7进行左右翻转得到的结果。

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

对于矩阵的处理有很多,但在这里只需要用到两种:

  1. 旋转90度(顺时针,逆时针都可以)
  2. 左右翻转

所以最终问题转变为如何实现对List表示的二维矩阵进行上述的两种操作。

使用列表生成式

列表生成式就是使用以下的方式来遍历生成一个新的表列: [ 变量表达式 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)

运行结果:

---------- 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度,再进行转置。

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之类,还是直接用库吧。

完整源码

最后附上完整的代码: 完整源码

转载于:https://my.oschina.net/u/1156588/blog/2992382

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值