1、列表解析:

  • 举例:生成一个列表,元素0-9,对每一个元素自增1后求平方返回新列表。
test = [ (i + 1) ** 2 for i in range(10)]
print(test) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]test = []
for i in range(10):test.append((i + 1) ** 2)
print(test) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

可以看出,是将一个for循环拉平,放到一个列表中。(不是简单的拉平!!)

  • 语法:

[ 返回值 for 元素 in 可迭代带对象 if 条件 ]
使用中括号 [] ,内部是for 循环 ,if条件语句可选
返回一个列表

  • 列表解析式是一种语法糖:

编译器会优化,不会因为简写而影响效率,反而因优化提高了效率
减少程序员工作量,减少出错
简化了代码,但是可读性增强

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:579817333
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
# newlist = [print(i,end='') for i in range(10)]
print(newlist)
# 0123456789[None, None, None, None, None, None, None, None, None, None]
# print是打印,并不是解析式生成的值,只不过没循环一次,列表中追加一个None而已newlist = []
for i in range(10):print(i, end='')newlist.append(None)
print(newlist)#0123456789[None, None, None, None, None, None, None, None, None, None]# 获取10以内的偶数
# lst = [ i for i in range(10) if not i % 2]
# print(lst) # [0, 2, 4, 6, 8]
# lst = [ i for i in range(10) if  i % 2 == 0]
# print(lst) # [0, 2, 4, 6, 8]

举例

lst = [i for i in range(21) if not i % 2 if not i % 3]
print(lst) # [0, 6, 12, 18]
lst = [i for i in range(21) if  i % 2 == 0 if i % 3 == 0]
print(lst) # [0, 6, 12, 18]lst = [i for i in range(21) if not i % 2 elif not i % 3]
print(lst) # 这样是会抛SyntaxError异常lst = []
for i in range(21):if i % 2 ==0:lst.append(i)elif i % 3 == 0:lst.append(i)
print(lst)
# [0, 2, 3, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20]

首先,结果不满足,其次,如果有elif 同一层的语句,是不能写成如上的解析式的。

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:579817333
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
lst = []
for i in range(21):if i % 2 ==0 and i % 3 == 0:lst.append(i)
print(lst) # [0, 6, 12, 18]#-------->lst = [ i for i in range(21) if not i % 2 and  i % 3 ==0]
print(lst) # [0, 6, 12, 18]lst = [ i for i in range(21) if not i % 2 or  i % 3 ==0]
print(lst) # [0, 2, 3, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20]

 lst = [i for i in range(21) if  i % 2 == 0 if i % 3 == 0] # 在第一个if下执行第二个iflst = [ i for i in range(21) if not i % 2 and  i % 3 ==0] # 直接将两个if 条件合并
# 这两个是等价的

注:循环条件都是一层一层的,第一层for下,执行第二层for,以此类推。

举例-陷阱

t1 = [[x,y] for x in 'abced' for y in range(3)]
print(t1)
# [['a', 0], ['a', 1], ['a', 2], ['b', 0], ['b', 1], ['b', 2], ['c', 0], ['c', 1], ['c', 2], ['e', 0], ['e', 1], ['e', 2], ['d', 0], ['d', 1], ['d', 2]]t2 = [{x,y} for x in 'abced' for y in range(3)]
print(t2)
# [{0, 'a'}, {1, 'a'}, {2, 'a'}, {0, 'b'}, {1, 'b'}, {2, 'b'}, {0, 'c'}, {1, 'c'}, {2, 'c'}, {0, 'e'}, {1, 'e'}, {2, 'e'}, {0, 'd'}, {1, 'd'}, {2, 'd'}]t2 = [{x:y} for x in 'abced' for y in range(3)]# [{'a': 0}, {'a': 1}, {'a': 2}, {'b': 0}, {'b': 1}, {'b': 2}, {'c': 0}, {'c': 1}, {'c': 2}, {'e': 0}, {'e': 1}, {'e': 2}, {'d': 0}, {'d': 1}, {'d': 2}]

分析三种不同顺序的结果

t1 = [(i, j) for i in range(7) if i > 4 for j in range(20,25) if j > 23]
print(t1)
# 相比下面的两种个,这个效率略有提高,先比较,在进入下一次循环,但是也没什么事t2 = [(i, j) for i in range(7) for j in range(20,25)if i > 4 if j > 23]
print(t2)t3 = [(i, j) for i in range(7) for j in range(20,25)if i > 4 and j > 23]
print(t3)# [(5, 24), (6, 24)]
# [(5, 24), (6, 24)]
# [(5, 24), (6, 24)]
  • 练习题:

打印九九乘法表

1*1=1
1*2=2  2*2=4
1*3=3  2*3=6  3*3=9
1*4=4  2*4=8  3*4=12 4*4=16
1*5=5  2*5=10 3*5=15 4*5=20 5*5=25
1*6=6  2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7  2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8  2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9  2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81['0001.lkbjmbfcwj', '0002.ciebvklpie', '0003.sjwtcakjjk', '0004.kuiivvfoai', '0005.ymaetkbdrt', '0006.ayhlrgedoh', '0007.xdjnaysdct', '0008.qkakrtdebv', '0009.jytyhtnwkc', '0010.rbxkiuetev', '0011.plhdxcdyvq', '0012.ubkudcrisb', '0013.yoceaqjvna', '0014.aeirhriutw', '0015.yemotxgfin', '0016.tehmlunsgy', '0017.seobircuxq', '0018.nxofutxipl', '0019.lbtmvkrhnj', '0020.rowntjaqpp', '0021.oadngppkty', '0022.ftdeifipph', '0023.fwuxgxgovt', '0024.bjnaxoqsxd', '0025.jhkjanttrr', '0026.eoutbjinyq', '0027.agdidptkcu', '0028.ccofruyutd', '0029.suchksvbva', '0030.ucvrshekrf', '0031.qikrlpilqi', '0032.ffdfqosxnh', '0033.jtotgqsdgm', '0034.jxssbjnclg', '0035.qandynxfat', '0036.ygodstktip', '0037.qklhxypdba', '0038.vlghicldkp', '0039.jbpyieqxkc', '0040.dcybelgsew', '0041.bumewnipnp', '0042.koqdtxfain', '0043.wpjdhnduah', '0044.vledqpcnpd', '0045.bkjisgagaj', '0046.ymdthjiphw', '0047.avqxthoilm', '0048.wsxtulxfnl', '0049.tmvdcqovcf', '0050.jcfnuaqfob', '0051.tpptnvysyv', '0052.bsmfywydnw', '0053.ivqotuhhgp', '0054.nfryeqntta', '0055.eyoxwwtuhl', '0056.hgtnxluwqy', '0057.buabekigsu', '0058.dxbflmyknn', '0059.bibmwmoitm', '0060.mmbyibfeeg', '0061.ulythfirrd', '0062.rnamiseafs', '0063.abpbtceqpd', '0064.fawoscqiub', '0065.aunqntadxh', '0066.owavtvxdrq', '0067.ahnioayayy', '0068.ojbuyqvmxf', '0069.svbqsppkes', '0070.ncqojtdtlg', '0071.hmbtvsuwah', '0072.iwqykfsisp', '0073.fymolgcbnh', '0074.txhnidqufy', '0075.icmhrnifjx', '0076.dvctqrjyhe', '0077.nqncmelbys', '0078.gbaqnpaxyy', '0079.gfirdjcrao', '0080.qcguhuqdwk', '0081.kuqellfomi', '0082.kpltlguvcc', '0083.lfeserogau', '0084.imgwnglrob', '0085.dvtcjupmmk', '0086.evswireebh', '0087.tlbordvirb', '0088.eleixowhur', '0089.mvpwqiottn', '0090.iokdlfvipt', '0091.tqeuiulywc', '0092.twrfdissos', '0093.ylbtevnroy', '0094.uvtifqqdny', '0095.kxrhorowny', '0096.qcygokxvys', '0097.gvlufbmctq', '0098.jmqgjidgxv', '0099.gxvbreoimr', '0100.ljjjoelvna']

‘0001.ababsdgcfe’ 这样的id ,从0001 - 0100

lst = [i **2 for i in range(1, 11)]lst = [1,2,3,4,5]
newlist = [lst[i] + lst[i + 1]  for i in range(len(lst) - 1)]
print(newlist) # [3, 5, 7, 9]cf = [ print('{}*{}={:<2}'.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(cf)print('\n'.join([' '.join(['{}*{}={:<2}'.format(j, i, i * j)  for j in range(1, i + 1)] ) for i in range(1, 10) ]))import random
alpha = bytes(range(97,122)).decode()# lst = ['{:04}.{}'.format(i,''.join([random.choice(alpha) for _ in range(10)])) for i in range(1, 101)]
# print(lst)l = random.choices(alpha,k = 10) #  ['u', 't', 'h', 'x', 'v', 'g', 'c', 'p', 'l', 'n']
s1 = ''.join(l)l = ''.join(random.sample(alpha,10)) # 如果用sample的话,就没有重复的字母,上面的choice 或choices是有重复字母的可能性的
print(l)

2、生成器表达式:

定义:

生成器就是迭代器,可以理解为一种数据类型,这种数据类型实现了迭代器协议,其他的数据类型需要调用自己内置的__iter_方法,所以生成器就是可迭代对象。

生成器分类以及在Python中的表现形式:(Python有两种不同的方式提供生成器)

①生成器函数:常规函数定义,但是,使用yield 语句代替return语句,但是,yield在同一层函数中,可以多次使用,一次返回一个结果,返回一个结果后,将函数设置为挂起状态,以便下次从他离开的地方继续执行。

②生成器表达式:类似于列表的推导,但是生成器返回按需产生结果的一个对象,而不是一次性构建一个结果列表。

语法:

  • (返回值 for 元素 in 可迭代对象 if 条件)
  • 列表解析式的中括号换成小括号
  • 返回一个生成器

和列表解析式的区别:

  • 生成器表达式是按需计算(或惰性求值,延迟计算)需要的时候才算值。
  • 列表解析式是立即返回值

生成器:

  • 可迭代对象
  • 迭代器

举例:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:579817333
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
g = ('{:04}'.format(i) for i in range(1,11))
print(g)a = next(g)for i in g:print('i',i)
print('------------------')
for j in g:print('j',j)

结果:

# 可以看出g 是一个生成器对象 generator
# next(g) 表示地址指针向下走一步
# 第一个for循环就将g 迭代完了
# 所以第二个for就没法往下进行迭代
# 因为生成器是无法向列表那样,一致迭代,当地址指针到了最后一个后,用next() 再迭代会报错
<generator object <genexpr> at 0x0000000001D9D318>
i 0002
i 0003
i 0004
i 0005
i 0006
i 0007
i 0008
i 0009
i 0010
------------------

对比:列表解析式:

g = ['{:04}'.format(i) for i in range(1,11)]
print(g)for i in g:print('i',i)
print('------------------')
for j in g:print('j',j)['0001', '0002', '0003', '0004', '0005', '0006', '0007', '0008', '0009', '0010']
i 0001
i 0002
i 0003
i 0004
i 0005
i 0006
i 0007
i 0008
i 0009
i 0010
------------------
j 0001
j 0002
j 0003
j 0004
j 0005
j 0006
j 0007
j 0008
j 0009
j 0010

总结:

生成器,延迟计算(惰性求值),返回迭代器,可以迭代,从前往后走一遍,不能回头。

列表解析式:立即求值,返回的不是迭代器,是可迭代对象,从前往后走一遍后,可以回头

注:

it = (print('{}'.format(i + 1)) for i in range(2))first = next(it)second = next(it)val = first + second1
2
--------------------------------------------------------------------------
TypeError                                Traceback (most recent call last)
<ipython-input-10-8a69cb4a56e0> in <module>()5 second = next(it)6
----> 7 val = first + secondTypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'# 事实上,it 生成器(generator)里边是None,print 是打印,
# 所以每次next(it) 的时候,要执行一次print(...),同时将None 赋值给变量

例子

 it = (x for x in range(10) if x %2)first = next(it)second = next(it)val = first + secondprint(val) # 4

生成器和列表解析式的对比:

  • 计算方式:
    生成器表达式延迟计算,列表解析式立即计算
  • 内存占用:
    单从返回值本身来说,生成器表达式省内存,列表解析式能返回新的列表
    生成器没有数据,内存占用极少,但是使用的时候,虽然一个个返回数据,但是合起来占用的内存也差不多
    列表解析式构造新的列表需要占用内存
  • 计算速度:
    单看计算时间看,生成器表达式好事非常短,列表解析式耗时长
    但是生成器本身并没有返回任何值,只返回一个生成器对象
    列表解析式构造并返回一个新的列表

注:

使用内建函数 iter() 可以将一个可迭代对象转换为一个生成器。iter([1,2,3])

 b = iter(range(4))next(b) # 一直是0 ,因为每next一次,从新建一个生成器,所以一直在0的位置a = iter(range(4))for i in a :print(i) # 0,1,2,3,

迭代器没有 len() 这个attribution

3、集合解析式 Python3.x新增

语法:

{ 返回值 for 元素 in 可迭代对象 if 条件}
列表解析式的中括号,换位大括号
立即返回一个集合

用法:

{ (x, x + 1) for i in range(10) }
{ [x] for x in range(10)} # 这个会报错,[x ] ,集合中 不能有不可hash的

4、字典解析:Python3 新增

语法:

{ 返回值 for 元素 in 可迭代对象 if 条件}
使用 k-v 形式
立即返回一个字典

用法:

a = {x:(x, x + 1) for x in range(4)}
print(a) # {0: (0, 1), 1: (1, 2), 2: (2, 3), 3: (3, 4)}
b = {x:[x, x + 1] for x in range(4)}
print(b) # {0: [0, 1], 1: [1, 2], 2: [2, 3], 3: [3, 4]}
c = {(x,):[x, x + 1] for x in range(4)}
print(c) # {(0,): [0, 1], (1,): [1, 2], (2,): [2, 3], (3,): [3, 4]}
d = {[x]:[x, x + 1] for x in range(4)}
print(d) # TypeError
e = {chr(0x41 + x):x ** 2 for x in range(4)}
print(e) # {'A': 0, 'B': 1, 'C': 4, 'D': 9}
f = {str(x):y  for x in range(4) for y in range(3)}
print(f) # {'0': 2, '1': 2, '2': 2, '3': 2}  覆盖

5、总结:

——生成器相对解析式而言,生成器主要节省了内存,事实上,效率上并没有明显的提高,所以一般只考虑内存问题就可以。

——Python2 映入列表解析式

——Python2.4 引入生成器表达式

——Python3 引入集合,字典解析式,并迁移到2.7

——一般来说,应该多用解析式,简短,高效,如果一个解析式非常复杂,要考虑拆解用for循环

——生成器和迭代器是不同的对象,但是都可迭代对象,迭代器可以用next()

——生成器是迭代器,迭代器不一定是生成器, iter(range(4)) 不是生成器生成的

Python-各种结构解析以及生成器(列表解析,字典解析,集合解析,元组构成的生成器)相关推荐

  1. Python学习笔记:列表、字典与集合解析(List, Dict and Set Comprehensions)

    Python学习笔记:列表.字典与集合解析(List, Dict and Set Comprehensions) 1.列表解析 最受喜爱的Python语言特性.过滤一个集合的元素生成一个新的列表. 一 ...

  2. python有几种容器_Python中几种内置的容器(Containers)类型:列表、字典、集合和元组的比较和该注意的点...

    之所以称他们为容器类型是因为他们不像基本类型那样只有一种简单类型的数据,而是可以包含其他类型的数据,numpy的计算速度比原生Python快的一个很重要的原因就是numpy中的数组(类似于Python ...

  3. python.集合转列表_Python基础数据类型:元组、列表、字典、集合

    你好,我是goldsunC. 让我们一起进步吧! 元组.列表.字典.集合 元组和列表是Python语言中非常重要的一部分内容,它们是Python中除了字符串以外的另两种序列结构,几乎在任何地方都少不了 ...

  4. 【Python基础】使用列表、字典和集合生成式来缩短代码

    作者 | Philip Wilkinson 编译 | VK 来源 | Towards Datas Science 在使用Python将近一年的时间里,我经常遇到"生成式"这个词,但 ...

  5. Python序列 数据类型 创建方式 Tuple元组 Str字符串 List列表 dict字典 Set集合 range,zip,map,enumerate

    Python 序列分类 数据类型 详细介绍 Python 主要数据类型: 元组Tuple, 字符串Str,列表List,字典Dict,集合Set 对比 元组Tuple 字符串Str 列表List 字典 ...

  6. Day2 - Python基础2 列表、字典、集合 --转自金角大王

    Day2 - Python基础2 列表.字典.集合 --转自金角大王 Posted on 2018-01-24 13:23 Byd_lei 阅读(41) 评论(0)  编辑 收藏 本节内容 列表.元组 ...

  7. 数据结构:元祖、列表、字典、集合概念及区别

    元祖(tuple): 1.任意对象的有序集合  2.通过偏移存取 3.属于不可变序列类型(一旦创建不支持任何修改,即为只读) 4.固定长度.异构.任意嵌套 a = (1,2,3,"d&quo ...

  8. Day2 - Python基础2 列表、字典、集合

    Python之路,Day2 - Python基础2 本节内容 列表.元组操作 字符串操作 字典操作 集合操作 文件操作 字符编码与转码 1. 列表.元组操作 列表是我们最以后最常用的数据类型之一,通过 ...

  9. python使用while循环来处理列表和字典--小任务2

    for循环是一种遍历列表的有效方式,但在for循环中不应修改列表,否则将导致Python难以跟踪其中的元素.要在遍历列表的同时对其进行修改,可使用while循环.通过将while循环同列表和字典结合起 ...

  10. Python -- 使用while循环来处理列表和字典

    使用while循环来处理列表和字典 要记录大量的用户和信息,需要在while循环中使用列表和字典. for循环是一种遍历列表的有效方式,但在for循环中不应修改列表,否则将导致Python难以跟踪其中 ...

最新文章

  1. 在CentOS 6.3 64bit上安装最新版tsar并监控ATS 5.3
  2. 搭建squid代理服务器
  3. MongoDB 和 NoSQL简介
  4. Linux 内核定时器使用 一 低精度定时器
  5. influxdb mysql对比_InfluxDB读写性能测试
  6. java 生成校验验证码_java生成验证码并进行验证
  7. (59)Verilog HDL测试激励:时钟激励1
  8. All Friends 极大团
  9. 全国计算机一级试题重难点,全国计算机等级考试一级MS选择题(重难点)部分.doc...
  10. 【DIY】自动鱼缸控制系统——【三】
  11. UDP测试工具(ace版本)
  12. 一文盘点中国商业航天:民营火箭的两类瓶颈和三大趋势
  13. 简易计算器,你值得拥有
  14. 深圳入职两周的感想——防止入坑
  15. android 语音识别文字
  16. Python matplotlib 饼图
  17. python中hasattr,getattr,setattr的区别
  18. qq视频转码失败怎么办_腾讯云点播视频转码需要注意的问题
  19. tixati中文版下载 | Tixati(bt下载器)官方中文版V2.88 | 敏感资源无法下载怎么解决?
  20. 实验5-6 使用函数判断完全平方数 (10分)

热门文章

  1. 【2】基于zookeeper,quartz,rocketMQ实现集群化定时系统
  2. 面试宝典_Python.常规算法.0002.输出任意两个字符串中最长公共子串?
  3. AC日记——计算多项式的导函数 openjudge 1.5 38
  4. 运维中心建设--服务台建设一期
  5. 【博客话题】感谢您,我的老师
  6. python列表解析式如何使用_python列表推导式操作解析
  7. python 将dataframe中的str都转化成float_【Python自学笔记】一次不太成功的利用Python整理的利润表实践...
  8. 【学习笔记】Python - PyQt
  9. 数据表_事物码(Transaction Code)信息
  10. 37、Power Query-不使用IF嵌套进行匹配