博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python3中二维List数据的三种处理方法及比较
阅读量:6267 次
发布时间:2019-06-22

本文共 4360 字,大约阅读时间需要 14 分钟。

hot3.png

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.11 23 4No.2: 2 14 3No.3:2 41 3No.44 2 3 1No.54 3 2 1No.63 41 2No.71 32 4N0.83 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## 使用numpydef 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

你可能感兴趣的文章
centos7 crontab笔记
查看>>
.Net AppDomain.CurrentDomain.AppendPrivatePath(@"Libs");
查看>>
【Unity3D基础教程】给初学者看的Unity教程(零):如何学习Unity3D
查看>>
Android Mina框架的学习笔记
查看>>
合并两个排序的链表
查看>>
rtf格式的一些说明,转载的
查看>>
REST Security with JWT using Java and Spring Security
查看>>
echarts学习总结(二):一个页面存在多个echarts图形,图形自适应窗口大小
查看>>
IIS7显示ASP的详细错误信息到浏览器
查看>>
使用fiddler对手机APP进行抓包
查看>>
exit和_exit的区别
查看>>
Javascript、Jquery获取浏览器和屏幕各种高度宽度(单位都为px)
查看>>
php不重新编译,安装未安装过的扩展,如curl扩展
查看>>
JavaScript编码encode和decode escape和unescape
查看>>
ppp点对点协议
查看>>
html5游戏开发-简单tiger机
查看>>
Codeforces 712C Memory and De-Evolution
查看>>
编写的windows程序,崩溃时产生crash dump文件的办法
查看>>
Ural2110 : Remove or Maximize
查看>>
Django REST framework 的TokenAuth认证及外键Serializer基本实现
查看>>