python之列表解析

1. 介绍

列表解析是最常应用迭代协议的环境之一,与for循环一起使用。先看一个简单的例子:

#for循环
L=[1,2,3,4,5]
for i in range(len(L)):
    L[i]+=10           #result:L=[11,12,13,14,15]
#等效于
#列表解析
L=[1,2,3,4,5]
L=[x+10 for x in L]     #result:[11,12,13,14,15]

从技术上来讲,列表解析并非真的是必需的,因为我们总可以用一个for循环手动构建一个表达是结果的列表。但是,列表解析编写更加精简,运行速度更快(快一倍)。

2.在文件上使用列表解析

f=open('salary.txt')
lines=f.readlines()
print(lines)
#result:['lastName hoursWorked hourlyWage\n', 'Bob 4 80\n', 'Ann 8 160\n']
#利用列表解析去掉每行末尾的换行符(\n)
#rstrip方法:移除右端空白,或采用line[:-1]分片也可以
lines=[line.rstrip() for line in lines]
print(lines)
#result:['lastName hoursWorked hourlyWage', 'Bob 4 80', 'Ann 8 160']

3.扩展的列表解析语法

一个非常有用的扩展:表达式中的嵌套的for循环可以有一个相关的if子句,来过滤那些测试不为真的结果项。

#找出1~9的三次方中的偶数项
#方法1:列表解析+if判断
even=[x**3 for x in range(1,10) if x%2==0]
print(even)  #result: [8, 64, 216, 512]
#方法2:列表解析+filter+lambda函数
even=list(filter((lambda x:x%2==0),[x**3 for x in range(1,10)]))
print(even)  #result: [8, 64, 216, 512]
#方法3:map+filter+lambda函数(列表解析比map函数运行要快一点,map函数对for循环要快2倍)
even=list(filter(lambda x:x%2==0,map((lambda x:x**3),range(1,10))))
print(even)  #result: [8, 64, 216, 512]

构建一个x+y连接的列表

#将一个字符串中的每一个x和另一个字符串中的每个y连接起来
lst=[x+y for x in 'abc' for y in 'lmn']
print(lst)    #result:['al', 'am', 'an', 'bl', 'bm', 'bn', 'cl', 'cm', 'cn']

4.列表解析和矩阵(又称多维数组)

创建多维矩阵(注意行列值的位置):

#创建一个row行col列的零矩阵,其中row和col需要提前定义
row=5
col=6
#方法1:列表解析
arr1=[[0 for c in range(col)] for r in range(row)]
#方法2:最不建议使用!!!因为当对其中某一个值赋值时,会导致该值所在列皆发生改变
arr2=[[0]*col]*row
#方法3:numpy中的zeros函数,dtype默认float64,若为整型,需自定义
import numpy as np
arr3=np.zeros((row,col),dtype=int)

常见操作:

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

#提取行
M[1]    #return:[4,5,6]

#提取列,其中row是自定义变量,没有特殊含义,不是固定的,且只能行遍历
#方法1:第一轮循环:row=[1,2,3];第二轮循环:row=[4,5,6];第三轮循环:row=[7,8,9]
[row[1] for row in M]   #return:[2,5,8]
#方法2:
[M[row][1] for row in range(3)]    #return:[2,5,8]

#提取对角线(假设矩阵有相同的数目的行和列)   
[M[i][i] for i in range(len(M))]    #return:[1, 5, 9]

#两个矩阵对应元素的乘积,注意第二个的col和row的位置
[M[row][col]*N[row][col] for row in range(3) for col in range(3)]
#return:[2, 4, 6, 12, 15, 18, 28, 32, 36]
[[M[row][col]*N[row][col] for col in range(3)] for row in range(3)]
#return:[[2, 4, 6], [12, 15, 18], [28, 32, 36]]

5.集合解析和字典解析

#集合解析
{x*x for x in range(10)}      #result:{0, 1, 4, 9, 16, 25, 36, 49, 64, 81}
#等效于:
set(x*x for x in range(10))   #result:{0, 1, 4, 9, 16, 25, 36, 49, 64, 81}

#集合解析拓展
{x*x for x in range(10) if x%2==0}   #result:{0, 4, 16, 36, 64}
#注意:这里有个项(12)被合并了,因为12出现了两次
{x*y for x in [1,2,3] for y in [4,5,6]} #result:{4, 5, 6, 8, 10, 12, 15, 18}


#字典解析
{x:x*x for x in range(10)}
#result:{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
#等效于:
dict((x,x*x) for x in range(10))
#result:{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

#字典解析拓展
{x:x*x for x in range(10) if x%2==0}  #result:{0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
#正常应该为{1:4,1:5,1:6,2:4,2:5,2:6,3:4,3:5,3:6},但由于一个key只能对应一个value,因此保留最晚更新的那个
{x:y for x in [1,2,3] for y in [4,5,6]}  #result:{1: 6, 2: 6, 3: 6}


  • 10
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值