首页 > 其他 > 详细

生成器表达式、集合解析式、字典解析式

时间:2019-10-14 21:40:55      阅读:98      评论:0      收藏:0      [点我收藏+]

生成器表达式

生成器的语法为:(返回值 for 元素 in 可迭代对象 if 条件) ,它就是将列表解析式的中括号换成小括号就行了 。它返回的是一个可迭代的生成器对象。

(x for x in range(1,5))

结果为:
<generator object <genexpr> at 0x03F3F1B0>

 

生成器和列表解析式的区别 

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

生成器是一个迭代器,也是可迭代对象。

#延迟计算,返回迭代器,可以迭代, 从前到后走完一遍后,不能回头
g = ("{:04}".format(i) for i in range(1,11))

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

结果为:
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
~~~~~~~~~~~~

#立即计算,返回的不是迭代器,返回可迭代对象列表,从前到后走完一遍后,可以重新回头迭代
 
g = ["{:04}".format(i) for i in range(1,11)]
for x in g:
    print(x)
print(~~~~~~~~~~~~)
for x in g:
    print(x)

结果为:

0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
~~~~~~~~~~~~
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010

比如it = (print("{}".format(i+1)) for i in range(2))
first = next(it)
second = next(it)
val = first + second
val的值是什么? 答案是不能相加
val = first + second 语句之后能否再次next(it)? 不能再next

it = (print("{}".format(i+1)) for i in range(2))#IT是生成器
first = next(it)
second = next(it)
val = first + second

结果为:
1
2
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-175-9bc925c5dd92> in <module>
      2 first = next(it)
      3 second = next(it)
----> 4 val = first + second

TypeError: unsupported operand type(s) for +: NoneType and NoneType


next(it)

结果为:
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-176-bc1ab118995a> in <module>
----> 1 next(it)

StopIteration: 

it = (x for x in range(10) if x % 2)
first = next(it)
second = next(it)
val = first + second
val的值是什么?4
val = first + second 语句之后能否再次next(it)? 能

it = (x for x in range(10) if x % 2)
first = next(it)
print(first)
second = next(it)
print(second)
val = first + second
print(val)
an = next(it)
print(an)

结果为:
1
3
4
5

生成器表达式和列表解析式对比

计算方式生成器表达式延迟计算,列表解析式立即计算

内存占用:单从返回值本身来说,生成器表达式省内存,列表解析式返回新的列表。生成器没有数据,内存占用极少,但是使用的时候,虽然一个个返回数据,但是合起来占用的内存也差不多。列表解析式构造新的列表需要占用内存。

计算速度:单看计算时间看,生成器表达式耗时非常短,列表解析式耗时长,但是生成器本身并没有返回任何值,只返回了一个生成器对象,列表解析式构造并返回了一个新的列表 。

集合解析式 

集合解析式的语法: {返回值 for 元素 in 可迭代对象 if 条件},列表解析式的中括号换成大括号{}就行了,它会立即返回一个集合。

{(x,x+1) for x in range(10)}

结果为:
{(0, 1),
 (1, 2),
 (2, 3),
 (3, 4),
 (4, 5),
 (5, 6),
 (6, 7),
 (7, 8),
 (8, 9),
 (9, 10)}
{[x] for x in range(10)} 

{[x] for x in range(10)} 

结果为:
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-189-5bb81d40d8ae> in <module>
----> 1 {[x] for x in range(10)}

<ipython-input-189-5bb81d40d8ae> in <setcomp>(.0)
----> 1 {[x] for x in range(10)}

TypeError: unhashable type: list

字典解析式

字典解析式的语法:{返回值 for 元素 in 可迭代对象 if 条件},列表解析式的中括号换成大括号{}就行了,使用key:value形式,它会立即返回一个字典。

 {x:(x,x+1) for x in range(10)}

结果为:
{0: (0, 1),
 1: (1, 2),
 2: (2, 3),
 3: (3, 4),
 4: (4, 5),
 5: (5, 6),
 6: (6, 7),
 7: (7, 8),
 8: (8, 9),
 9: (9, 10)}

{x:[x,x+1] for x in range(10)}

结果为:

{0: [0, 1],
 1: [1, 2],
 2: [2, 3],
 3: [3, 4],
 4: [4, 5],
 5: [5, 6],
 6: [6, 7],
 7: [7, 8],
 8: [8, 9],
 9: [9, 10]}

{(x,):[x,x+1] for x in range(10)}

结果为:
{(0,): [0, 1],
 (1,): [1, 2],
 (2,): [2, 3],
 (3,): [3, 4],
 (4,): [4, 5],
 (5,): [5, 6],
 (6,): [6, 7],
 (7,): [7, 8],
 (8,): [8, 9],
 (9,): [9, 10]}


{[x]:[x,x+1] for x in range(10)} #

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-198-5f8fa7594e3f> in <module>
----> 1 {[x]:[x,x+1] for x in range(10)} #

<ipython-input-198-5f8fa7594e3f> in <dictcomp>(.0)
----> 1 {[x]:[x,x+1] for x in range(10)} #

TypeError: unhashable type: list

{chr(0x41+x):x**2 for x in range(10)}#16进制表示

结果为:
{A: 0,
 B: 1,
 C: 4,
 D: 9,
 E: 16,
 F: 25,
 G: 36,
 H: 49,
 I: 64,
 J: 81}

{str(x):y for x in range(3) for y in range(4)} # 输出多少个元素?

结果为:
{0: 3, 1: 3, 2: 3}

ret = {}
  for x in range(3):
    for y in range(4):
      ret[str(x)] = y#后面Y的值会覆盖前面的值
print(ret)

 

结果为:

{‘0‘: 3, ‘1‘: 3, ‘2‘: 3}

总结

一般来说,应该多应用解析式,简短、高效 ,如果一个解析式非常复杂,难以读懂,要考虑拆解成for循环 ,同时应该注意生成器和迭代器是不同的对象,但都是可迭代对象。

生成器表达式、集合解析式、字典解析式

原文:https://www.cnblogs.com/xpc51/p/11672491.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!