【python】列表解析式和生成器

转自: https://www.cnblogs.com/rivendare/p/9493698.html


列表解析式

可以根据已有列表,高效创建新列表的方式。列表解析是Python迭代机制的一种应用,它常用于实现创建新的列表,返回的是一个列表,因此用在[]中。

列表解析式因编译器进行优化,提高了效率,减少出错,增加可读性

语法

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

 示例1:

生成一个列表,元素0-9,对每一个元素自增1后求平方返回新列表

#常规写法
new = []
for i in range(10):
    new.append((i+1)**2)
print(new)

#使用列表解析式方法
new = [(i+1)**2 for i in range(10)]
print(new)

 输出结果相同:

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

 

示例2:

获取10以内的偶数

list = [i for i in range(10) if i % 2 == 0]
print(list)

输出结果为:

[0, 2, 4, 6, 8]

示例3:

20以内,即能被2整除又能被3整除的数

#以下两种方法都可以
list1 = [i for i in range(20) if i % 2 == 0 if i % 3 == 0]        #方法一
list2 = [i for i in range(20) if i % 2 == 0 and i % 3 == 0]       #方法二

 

列表解析式进阶

  • [返回值 for i in 可迭代对象A for j in 可迭代对象B]
  • 等价于:

      list = []

        for i in iterableA:

          for j in iterableB:

            list.append(expr)

示例1:

list1 = [(x,y) for x in "abc" for y in range(3)]
list2 = [[x,y] for x in "abc" for y in range(3)]
list3 = [{x:y} for x in "abc" for y in range(3)]

print(list1)
print(list2)
print(list3)

输出:

[('a', 0), ('a', 1), ('a', 2), ('b', 0), ('b', 1), ('b', 2), ('c', 0), ('c', 1), ('c', 2)]
[['a', 0], ['a', 1], ['a', 2], ['b', 0], ['b', 1], ['b', 2], ['c', 0], ['c', 1], ['c', 2]]
[{'a': 0}, {'a': 1}, {'a': 2}, {'b': 0}, {'b': 1}, {'b': 2}, {'c': 0}, {'c': 1}, {'c': 2}]

 示例2:

#以下三种输出一样,但推荐使用第一种方法,效率更高
list1 = [(i,j) for i in range(7) if i>4 for j in range(20,25) if j >23]
list2 = [(i,j) for i in range(7) for j in range(20,25) if i>4 if j >23]
list3 = [(i,j) for i in range(7) for j in range(20,25) if i>4 and j >23]

print(list1)
print(list2)
print(list3)

输出:

[(5, 24), (6, 24)]
[(5, 24), (6, 24)]
[(5, 24), (6, 24)]

 

复杂示例:

1.返回1-10的平方列表

2.有一个列表list = [1,4,9,16,2,5,10,15],生成一个新列表。要去新列表元素是lst相邻2项的和

3.用列表解析式方法打印九九乘法表:

list = [1, 4, 9, 16, 2, 5, 10, 15]

list1 = [i**2 for i in range(1,11)]
list2 = [list[i] + list[i+1] for i in range(len(list)-1)]

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

 

生成器表达式

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

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

语法

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

生成器

  • 可迭代对象
  • 迭代器

生成器表达式示例:

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

 

  • 生成器进行延迟计算
  • 返回迭代器,可进行迭代
  • 对迭代器g使用next()方法,会将g拨动一下
  • 从前到后走完一遍后,不能回头

 

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

计算方式

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

内存占用

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

计算速度

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

 

集合解析式

语法

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

示例:

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

输出:

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

 注意,集合解析式中不能出现列表等不可hash的元素,否则编译器报错


 

字典解析式

语法

  • {返回值 for 元素 in 可迭代对象 if 条件}
  • 列表解析式的中括号[ ]换成大括号{ }
  • 使用key:value形式
  • 立即返回一个字典

 

示例:

a = {x:(x,x+1) for x in range(5)}
b = {x:[x,x+1] for x in range(5)}
c = {(x,):[x,x+1] for x in range(5)}
print(a)
print(b)
print(c)

输出:

{0: (0, 1), 1: (1, 2), 2: (2, 3), 3: (3, 4), 4: (4, 5)}
{0: [0, 1], 1: [1, 2], 2: [2, 3], 3: [3, 4], 4: [4, 5]}
{(2,): [2, 3], (0,): [0, 1], (3,): [3, 4], (1,): [1, 2], (4,): [4, 5]}

注意,字典解析式中的key不能出现列表等不可hash的元素,否则编译器报错

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值