21列表解析、生成器表达式

1、列表解析:函数式编程工具
列表解析是最常应用迭代协议的环境之一
列表解析也不是必须的,我们也可以手动循环来完成列表解析的工作,但是,列表解析看起来更加精简,
而且,列表解析比手动for循环执行速度更快,因为它们的迭代在解释器内部是以C语言的速度执行的,而不是以手动代码执行的
特别是对于较大的数据集合,这是列表解析的一个主要性能优点

l = [1,2,3,4,5,6]
l_new = [i for i in l if i%2==0] # (for i in l)就是一个可迭代对象
l = [x+y for x in 'abc' for y in 'lmn'] #['al', 'am', 'an', 'bl', 'bm', 'bn', 'cl', 'cm', 'cn']

 2、列表解析和map

复制代码
# 尽量让map调用和列表解析简单易懂
res = list(map(ord, 'spam'))
res = [ord(x) for x in 'spam'] #[115, 112, 97, 109]

res2 = [x ** 2 for x in range(10)]
res2 = list(map(lambda x: x**2, range(10))) #[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

res3 = [x for x in range(5) if x % 2 == 0]# 使用if分支的列表解析和filter()
res3 = list(filter((lambda x:x % 2 == 0), range(5)))

# 一个列表解析实现map+filter的功能
res4 = [x ** 2 for x in range(10) if x % 2 == 0]
res4 = list(map((lambda x:x**2),filter((lambda x:x%2 == 0),range(10)))) #[0, 4, 16, 36, 64]
复制代码

3、字典解析、集合解析
字典解析、集合解析只是把生成器表达式传递给类型名的语法糖
字典解析、集合解析可以在任何类型的可迭代对象上迭代,支持if,for

复制代码
s1 = {x*x for x in range(5)} #{0, 1, 4, 9, 16}
s2 = set(x*x for x in range(5)) #{0, 1, 4, 9, 16}
dic1 = {x:x*x for x in range(5)} #{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
dic2 = dict( (x,x*x) for x in range(5)) #{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

dic = {x+y: (ord(x),ord(y)) for x in 'ab' for y in 'cd'}
print(dic) #{'ac': (97, 99), 'ad': (97, 100), 'bc': (98, 99), 'bd': (98, 100)}

c = {c.lower() : c+'!' for c in 'spam'} #{'a': 'a!', 's': 's!', 'p': 'p!', 'm': 'm!'}
复制代码

 4、生成器表达式

把列表推导式的[]换成()
优点:省内存,一次只生成一个值在内存中
l_new = (i for i in range(50) if i%2==0)
for i in l_new:
    print(i)
# print(next(l_new))
# print(next(l_new))
# print(next(l_new))
# print(next(l_new))

例1、将names=['egon','alex_sb','wupeiqi','yuanhao']中的名字全部变大写 

复制代码
# 方法一
names=['egon','alex_sb','wupeiqi','yuanhao']
names_new = [i.upper() for i in names]
print(names_new)

# 方法二
names=['egon','alex_sb','wupeiqi','yuanhao']
name2 = map(lambda x:x.upper(),names)  #map得到的结果仍然是个迭代器
print(list(name2))
复制代码

例2、将names=['egon','alex_sb','wupeiqi','yuanhao']中以sb结尾的名字过滤掉,然后保存剩下的名字长度  

names=['egon','alex_sb','wupeiqi','yuanhao']
names2 = [len(i) for i in names if not i.endswith('sb')]
print(names2)

 例3、求文件a.txt中最长的行的长度(长度按字符个数算,需要使用max函数) 

with open('data.txt','r') as f:
    l = [len(line) for line in f]
print(max(l))

#还可以再精简些
with open('data.txt','r') as f:
    print(max(len(line)) for line in f)

  例4、求文件a.txt中总共包含的字符个数?思考为何在第一次之后的n次sum求和得到的结果为0?(需要使用sum函数) 

with open('data.txt','r') as f:
# with是上下文管理器,必须在with 里面,在外面print(g)的话,这时候文件已经关闭了
    s = (len(line) for line in f)#s此时是一个迭代器,一次在内容中只有一个值,所以print()函数必须在with里面,不然文件关闭了之后,就不能通过next()取值了
    # print(next(s))
    # print(next(s))
    print(sum(s))

 

posted @   cheng4632  阅读(96)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
历史上的今天:
2020-04-03 02python基础----控制流程
点击右上角即可分享
微信分享提示