Python学习之---列表解析+字典解析+集合解析+生成器表达式

列表解析List Comprehension

语法:
◆ [返回值 for 元素 in 可迭代对象 if 条件]
◆ 使用中括号[],内部是for循环,if条件语句可选
◆ 立即返回一个新的列表
优点
列表解析式是一种语法糖,引入一个新的概念:语法糖
语法糖(Syntactic sugar),是由Peter J. Landin(和图灵一样的天才人物,是他最先发现了Lambda演算,由此而创立了函数式编程)创造的一个词语,它意指那些没有给计算机语言添加新功能,而只是对人类来说更“甜蜜”的语法。语法糖往往给程序员提供了更实用的编码方式,有益于更好的编码风格,更易读。
在python语言中语法糖有三元表达式、列表生成式、列表生成器、迭代器等等,具体可参考如下博客:
https://segmentfault.com/a/1190000006261012

◆ 编译器会优化,不会因为简写而影响效率,反而因优化提高了效率
◆ 减少程序员工作量,减少出错
◆ 简化了代码,但可读性增强
基础语法格式
举例:

list1=[]
for i in range(10):
    list1.append(i)
print(list1)
>>>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
#变形后: 
print([i for i in range(10)])  

二者得到的答案是一致的,但是后者的代码量个简洁度明显低于前者.
条件语法格式
列表解析式还可以引进 if判断语句:
举例:
打印20以内既能被2整除又能被3整除的数:

print([i for i in range (1,20) if i%==0 if i %3 ==0])

只需要一行代码即可达到要求,而且还是嵌套的2层if.
嵌套循环语法
列表解析还可以嵌套两个for 循环

[(x,y)for x in range(3)for y in "abcd" ]#元组
[[x,y]for x in range(3)for y in "abcd" ]#列表嵌套
[{x,y}for x in range(3)for y in "abcd" ]#集合

生成器表达式:

语法
◆(返回值for 元素in 可迭代对象if 条件)
◆ 列表解析式的中括号换成小括号就行了
◆ 返回一个生成器
和列表解析式的区别
◆ 生成器表达式是按需计算(或称惰性求值、延迟计算),需要的时候才计算值
◆ 列表解析式是立即返回值生成器是可迭代对象,是一个迭代器

◆ 列表解析式最外层为[],生成器最外层为().要加以区分.

g=("{:04}".format(i)for i in range(1,11))
next(g)
for x in g:
	print(x)
print("~~~~~")
for x in g:
    print(x)

g=["{:04}".format(i)for i in range(1,11)]

for x in g:
	print(x)
print("~~~~~")
for x in g:
    print(x)

比较二者的输出结果可以看出,生成器表达式输出的结果比列表解析式的结果要少,这是因为生成器表达式的值在每一次Next()后,一次遍历结束将不再遍历,不能回头,所以只能走一遍.而列表解析式是生成的一个新的列表,所以可以重复遍历.

★ 和列表解析式的对比
计算方式
◆生成器表达式延迟计算,列表解析式立即计算
内存占用
◆单从返回值本身来说,生成器表达式省内存,列表解析式返回新的列表
◆生成器没有数据,内存占用极少,它是使用时一个个返回数据。如果将这些返回的数据合起来占用的内存也和列表解析式差不多。但是,它不需要立即占用这么多内存
◆列表解析式构造新的列表需要立即占用内存,不管你是否立即使用这么多数据
计算速度
◆单看计算时间看,生成器表达式耗时非常短,列表解析式耗时长
◆但是生成器本身并没有返回任何值,只返回了一个生成器对象
◆列表解析式构造并返回了一个新的列表,所以看起来耗时了

集合解析式

列表解析式的中括号换成大括号{}就行了

字典解析式

列表解析式的中括号换成大括号{}就行了
使用key:value形
立即返回一个字典

总结

◆ Python2 引入列表解析式
◆ Python2.4 引入生成器表达式
◆ Python3 引入集合、字典解析式,并迁移到了2.7
◆ 一般来说,应该多应用解析式,简短、高效
◆ 如果一个解析式非常复杂,难以读懂,可以考虑拆解成for循环生成器和迭代器是不同的对象,但都是可迭代对象可迭代对象范围更大,都可以使用for循环遍历

练习题:

第一题 使用列表解析式 打印九九乘法表

方法一 :

[print("{}*{}={:<3}".format(j,i,i*j),end ='\n' if i==j else "")for i in range(1,10) for j in range(1,i+1)]

方法二 :

[print("{}*{}={}{}".format(j,i,i*j,'\n' if i ==j else " "),end="") for i in range(1,10),for j in range(1,i+1)]

方法一 :


print(''.join([ "{}*{}={:<3}{}".format(j,i,i*j,'\n' if i==j else '')for i in range(1,10)for j in range(1,i+1)]))

第二题 使用列表解析式生成 “0001.abadicddws” 格式的ID号

要求ID格式是以点号分割,左边是4位从1开始的整数,右边是10位随机小写英文字母。
请依次生成前100个ID的列表,如下:

'0001.bbcomlkdyt'
'0002.yzjudytpna'
'0003.zycscjsvfy'
'0004.hhvqzlukui'
'0005.xissuxwsou'

方法一 :

import random
[print("{:04}.{}".format(i, ''.join([chr(random.randint(97,122))for i in range(10)])))for i in range(1,101)]

方法二 :

import random
[print("{:04}.{}".format(i, ''.join([random.choice(bytes(range(97,123)).decode())for i in range(10)])))for i in range(1,10)]

方法三 :

import random 
import string
[print("{:04}.{}".format(i,"".join([random.choice(string.ascii_lowercase) for j in range(10)]))) for i in range(1,101)]
#  引用string.ascii_lowercase 包进行提取随机的10个字符.

猜你喜欢

转载自blog.csdn.net/qq_40498551/article/details/89298652