python内置函数列表解析、生成器

  • 一、列表解析List Comprehension
  •  语法:[返回值 for i in 可迭代对象 if 条件]
  •  使用中括号[],内部是for循环,if条件判断语句是可选
  •  列表解析式返回一个新的列表
  •  列表解析式是一种语法糖,编译器会优化,不会因为简写而影响效率,反而会提高效率
  •  简化了代码,可读性增强
  • 举例:
1、生成一个列表,元素0-9,对每个元素自增1后求平方返回新列表
 >>> l1 = list(range(10))
 >>> l2 = [(i+1)**2 for i in l1]
 >>> l2
 [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
 
 2、求10以内的偶数
 >>> even = [x for x in range(10) if x%2==0]
 >>> print(even)
 [0, 2, 4, 6, 8]

 
•3、列表e返回都为None
 e = [print(i) for i in range(10)]
 
 4、20以内,既能被2整除又能被3整除的数
 >>> e = [i for i in range(20) if i%2==0 and i%3==0]
 >>> e
 [0, 6, 12, 18]

二、列表解析进阶

  • 语法:[返回值 for i in iterable1 for j in iterable2]
  • 等价于:
  • ret=[]
     for i in iterable1:
        for j in iterable2:
           ret.append(返回值)
  • 举例:
  [(x,y) for x in 'abcde' for y in range(3)]
  >>> [(x,y) for x in 'abcde' for y in range(3)]
  [('a', 0), ('a', 1), ('a', 2), ('b', 0), ('b', 1), ('b', 2), ('c', 0), ('c', 1), ('c', 2), ('d', 0), 
  ('d', 1), ('d', 2), ('e', 0), ('e', 1), ('e', 2)]
  
  >>> [(i,j) for i in range(7) if i>4 for j in range(20,25) if j>23]
  [(5, 24), (6, 24)]

三、生成器表达式

1、语法:

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

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

  •  生成器表达式是按需计算(或称为延迟计算),需要的时候才计算值
  •  列表解析式立即返回所有值
  •  举例: 
 >>> g = ("{:0}".format(i) for i in range(1,11))
 >>> next(g)
 '1'
 >>> for x in g:
 print(x)

四、生成器generator

  • 生成器指的是生成器对象,可以由生成器表达式得到,也可以使用yield关键字得到一个生成器函数,调用这个函数得到一个生成器对象

1、生成器函数

  •  函数体中包含yield语句的函数,返回生成器对象
  •  包含yield语句的生成器函数生成 生成器对象的时候,生成器函数的函数体不会立即执行
  •  next(generator)会从函数的当前位置向后执行到之后的碰到的第一个yield语句,会弹出值并暂停函数
  •  再次调用next函数,接着处理下一条yield语句,没有多余的yield语句被执行就会抛异常
  •  生成器对象是一个可迭代对象,是一个迭代器
  •  生成器对象,是延迟计算,惰性求值
  • 举例:
  >>> def inc():
    for i in range(5):
     yield i
   
  >>> print(type(inc))
  <class 'function'>
  >>> print(type(inc()))
  <class 'generator'>
  >>> x = inc()
  >>> print(type(x))
  <class 'generator'>
  >>> print(next(x))
  0
  >>> print(next(x))
  1

2、生成器函数的调用

  • 普通的函数调用fn(),函数会立即执行完毕,但是生成器函数可以使用next函数多次执行
  • 生成器函数等价于生成器表达式,只不过生成器函数可以更加的复杂
  • 举例
>>> def gen():
               print('line 1')
               yield 1
               print('line 2')
               yield 2
               print('line 3')
               return 3>>> next(gen())
  line 1
  1
  >>> next(gen())   # 函数被重新调用,所以每次执行next返回值一样
  line 1
  1
  >>> g = gen()  # 同一个函数
  >>> print(next(g))
  line 1
  1
  >>> print(next(g))
  line 2
  2
  >>> print(next(g))
  line 3
  Traceback (most recent call last):
    File "<pyshell#33>", line 1, in <module>
   print(next(g))
  StopIteration: 3

备注:在生成器函数中,使用多个yield语句,执行一次后会暂停执行,把yield表达式的值返回;再次执行会执行到下一个yield语句,return语句依然可以终止函数运行,但函数返回值不能被获取到

3、yield from的使用

例如:

yield from的使用
    def inc():
        yield from range(10)  #是一种语法糖
    foo=int()
    print(next(foo))


五、集合解析式

  •  语法:{返回值 for i in 可迭代对象 if 条件}
  •  列表解析式的中括号换成大括号就是集合解析式,返回是一个集合
  •  如:{(x,x+1) for x in range(10)}

六、字典解析式

  • 语法:{返回值 for i in 可迭代对象 if 条件}
  •  列表解析式的中括号换成大括号就是集合解析式
  •  使用key:value形式,返回一个字典
  •  如:{x:(x,x+1) for x in range(10)

七、可迭代对象

  •  能够通过迭代一次次返回不同的元素的对象,所谓相同不是指值是否相同,而是元素在容器中是否是同一个
  •  可以迭代,但是未必有序,未必可索引
  •  可迭代对象有:list,tupple,string,bytes,bytearray,range,set,dict,生成器等
  •  可以使用成员操作符in, not in ,in本质上就是遍历对象

八、迭代器

  •  特殊的对象,一定是可迭代对象,具备可迭代对象的特征
  •  通过iter方法把一个可迭代对象封装成迭代器
  •  通过next方法,迭代迭代器对象
  •  生成器对象就是迭代器对象
    for x in iter(range(10)):
        print(x)
    
    >>> g = ("{:0}".format(i) for i in range(1,11))
    >>> type(g)
    <class 'generator'>
    >>> next(g)
    '1'
    >>> next(g)
    '2'
    >>> 


 

原文地址:https://www.cnblogs.com/jiangzuofenghua/p/11385929.html