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

知识前导总结:

可迭代对象:

  1. 可以被for迭代,并且是可以回头继续打印
  2. 不能被next()函数输出

迭代器(iterator):

  1. 可以使用for循环输出迭代器中的项
  2. 可以被next()函数输出

    重点:迭代器一定是一个可迭代对象,但是可迭代对象未必是迭代器!
    重点:生成器对象一定是一个迭代器,但是迭代器未必是生成器对象!
    验证方法:

    next():内建函数,并且next输出是不可回头的!
        迭代器:
        # a = (i for i in range(10))
        # next(a) 返回 依次返回迭代的元素,并且是不可回头的
        可迭代对象:
        # a = [i for i in range(10)]
        # next(a) 返回 'list' object is not an iterator,对象不是一个迭代器
        iter():把可迭代对象转化为迭代器
        # iter(a)
        # next(iter(a)) # 如果不赋值给一个新的变量,每次返回都是iter函数包装的新的迭代器,可以使用id()查看
        #b = iter(a) # 把可迭代对象a转化为迭代器并赋值给b

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

计算方式:

  1. 生成器表达式延迟计算,惰性求值
  2. 列表解析式立即计算并返回

内存占用:

  1. 从返回值本身来说,生成器表达式省内存,返回的是一个生成器对象

  2. 而列表解析式直接计算完并返回一个新的列表

计算速度:

  1. 单从计算时间,生成器表达式耗时短,列表解析式耗时长

  2. 但是生成器本身并没有返回任何值也就是计算的结果,只返回一个生成器对象

  3. 列表解析式返回了一个计算后新的列表

1,列表解析List:

语法:

  1. [返回值 for 元素 in 可迭代对象 if 条件判断]
  2. 使用中括号[],内部是for循环,if条件语句可选
  3. 立即返回一个新的列表
  4. if条件判断可以使用逻辑元算符:and、or、not

定义和初始化:列表解析式是一种语法糖

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

列表解析式操作:

  1. 获取10以内的偶数

        # [i for i in range(0, 10, 2)]
        # numlist = [print(i) for i in range(10)],print函数会打印i输出到屏幕上,但是最后numlist中是None,因为print(i)的返回值都是None,并不返回i的值。可以使用type()函数擦查看!
    
  2. 例2:sorted返回的是一个列表,这是一个嵌套的的列表

        # nums = [sorted(range(10))]
        # len(nums) 返回1
    
  3. 下方每个字典都是单独的,所以并不是5个元素

        # [{x:y} for x in 'abcde' for y in range(3)]
    

生成器表达式:

语法:

  1. (返回值 for 元素 in 可迭代对象 if 条件)
  2. 生成器表达式使用小括号包裹

重点生成器表达式返回的是一个生成器(generator)对象!

  1. 生成器是可迭代对象
  2. 生成器和迭代器是不同的对象,但都是可迭代对象!

与列表解析式的区别:

  1. 生成器表示式是按需计算(或称惰性求值,延迟计算)
  2. 列表解析式是立即返回值
  3. 从开始到最后走完,不能再次迭代

生成器操作:

g = ("{:04}".format(i) for i in range(1, 11)) #返回  at 0x7f3db0814eb8>
next():可以输出生成器中的一个值

In [2]: it = (print("{}".format(i)) for i in range(2))
In [3]: it
Out[3]:  at 0x7faca927ffc0>

In [4]: [i for i in it]
0
1
Out[4]: [None, None]

In [5]: [i for i in it]
Out[5]: []

集合解析式:

语法:

  1. {返回值 for 元素 in 可迭代对象 if 条件}
  2. 集合解析式使用大括号{}
  3. 立即返回一个集合
  4. 集合解析式中计算的结果类型必须是可hash的类型

    集合解析式操作:
        1,{(x, x + 1) for x in range(10)} 返回 {(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)}
    

字典解析式:

语法:

  1. {返回值 for 元素 in 可迭代对象 if 条件}
  2. 使用大括号{}
  3. 使用key:value键值对形式,因为是字典不是集合
  4. 立即返回一个字典

字典解析式操作:

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

重点总结:

迭代器协议:

  1. 迭代器协议:对象需要提供next()方法,它要么返回迭代中的下一个元素或者下一项,要么就引起一个StopIteration异常,以终止迭代!
  2. 可迭代对象:实现了迭代器协议的对象
  3. 协议是一种约定,可迭代对象实现迭代器协议,Python的内置工具(如for循环,min,max函数等)使用迭代器协议访问对象!

例如:
1,在Python语言中可以使用for循环遍历列表,列表就是可迭代对象
for i in [i for i in range(5)]:
print(i)

生成器:生成器只能遍历一次!

Python使用生成器,而生成器具有惰性求值,延迟计算等特性,是指在需要的时候才会产生结果,而不是立即产生结果!比如列表解析式是立即返回一个列表,而生成器表达式返回的是一个生成器对象,只有当用for循环迭代时,才会取计算结果!

  1. 生成器函数:常规函数定义,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次从它离开的地方继续执行!
  2. 生成器表达式:类似于列表解析式,但是生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表!

你可能感兴趣的:(Python)