python 解析式生成式

列表解析List Comprehension

语法

  • [返回值 for 元素 in 可迭代对象 if 条件]

  • 使用中括号[],内部是for循环,if条件语句可选

  • 返回一个新的列表

列表解析式是一种语法糖

  • 编译器会优化,不会因为简写而影响效率,反而因优化提高了效率

  • 减少程序员工作量,减少出错

  • 简化了代码,但可读性增强

even = []
for x in range(10):
    if x % 2 == 0:
        even.append(x)
even = [x for x in range(10) if x % 2 == 0]

比较执行效率,可知,列表解析式的效率更快

思考

  • newlist = [print(i) for i in range(10)],请问newlist的元素打印出来是什么?

    [None, None, None, None, None, None, None, None, None, None]
    print()语句的返回值是None

  • 获取20以内的偶数,如果数字是3的倍数也打印[i for i in range(20) if i%2 == 0 elif i%3 == 0]可以吗?

    不可以,列表解释式内只可以使用if条件语句,elif不能使用

列表解析进阶

进阶1

[expr for item in iterable if coud1 if coud2]
  • 等价于
ret = []

for item in iterable:
    if coud1:
        if coud2:
        ret.append(expr)
  • 举例
[i for i in range(20) if i%2==0 and i%3==0]
[i for i in range(20) if i%2==0 if i%3==0]

进阶2

[expr for i in iterable1 for j in iterable2]
  • 等价于
ret = []

for i in iterable1:
    for j in iterable2:
        ret.append(expr)
  • 举例
[(x,y) for x in 'abcdef' for y in range(3)]
[[x,y] for x in 'abcdef' for y in range(3)]
[{x:y} for x in 'abcdef' for y in range(3)]

练习

  • 返回1-10平方的列表
lst = [ i**2 for i in range(10)]
  • 有一个列表lst = [1,4,9,16,2,5,10.15],生成一个新列表元素是lst相邻2项的和
lst = [1,4,9,16,2,5,10.15]
length = len(lst)

newlist = [lst[i]+lst[i+1] for i in range(length-1)]
  • 打印九九乘法表
lst = [['{}*{}={:2}'.format(j,i,i*j) for j in range(1,i)] for i in range(1,10)]
  • "0001.anjhesgxke"是ID格式,要求ID格式是以点号分割,左边是4位从1开始的整数,右边是10位随机小写英文字母。请依次生成前100个ID列表
import random
str ='abcdefghijklmnopqrstuvwxyz'

IDlist = ['{:04}.{}'.format(i,''.join(random.sample(str,10))) for i in range(1,101)]
print(IDlist)
import random

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

IDlist = ['{:04}.{}'.format(i, ''.join(random.sample(string.ascii_lowercase,10))) for i in range(1,101)]
print(IDlist)

生成器表达式Generator Expression

语法

  • (返回值 for 元素 in 可迭代对象 if 条件)

  • 列表解析式的中括号换成小括号就行了

  • 返回一个生成器

**和列表解析式的区别

  • 生成器表达式是按需计算(或称惰性求值、延迟计算),需要的时候才计算

  • 列表解析式是立即返回值

生成器

  • 可迭代对象

  • 迭代器

生成器表达式(二星重点)

和列表解析式的对比

  • 计算方式

    • 生成器表达式延迟计算,从头到尾走一遍,不能回头,列表解析式立即计算,可回头
  • 内存占用

    • 单从返回值本身来说,生成器表达式省内存,返回一个生成器对象,列表解析式返回新的列表

    • 生成器没有数据,内存占用极少,但是使用的时候,虽然一个个返回数据,但是合起来占用的内存也差不多

    • 列表解析式构造新的列表需要占用内存

  • 计算速度

    • 但看计算时间,生成器表达式耗时非常短,列表解析式耗时长

    • 但是生成器本身并没有返回任何值,只返回了一个生成器对象

    • 列表解析式构造并返回了一个新的列表

集合解析式

语法

  • { 返回值 for 元素 in 可迭代对象 if 条件 }

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

  • 立即返回一个集合

用法

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

字典解析式

语法

  • { 返回值 for 元素 in 可迭代对象 if 条件 }

  • 列表解析式的中括号换成大括号

  • 使用key:value形式

  • 立即返回一个字典

用法

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

总结

  • Python2 引入列表解析式

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

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

  • 一般来说,应该多应用解析式,简短,高效

  • 如果一个解析式非常复杂,难以读懂,要考虑拆解成for循环

  • 生成器和迭代器是不同的对象,但都是可迭代对象

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-09-05
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-10-05
  • 2021-10-31
猜你喜欢
  • 2021-08-05
  • 2021-11-02
  • 2022-01-10
  • 2022-12-23
  • 2021-09-08
  • 2022-12-23
  • 2021-08-01
相关资源
相似解决方案