zoukankan      html  css  js  c++  java
  • Python 生成器,列表推导

    生成器

    何为生成器?生成器就是自己用python代码写的迭代器,生成器的本质就是迭代器

    1 l1 = [1,2,3]
    2 iter1 = iter(l1)
    用以下两种方式构建一个生成器
    1. 通过生成器函数
    2. 生成器表达式

    生成器函数

    什么是生成器函数,它与普通的函数有什么区别?首先,我们举一个简单的函数,如:
    1 def func1(x):
    2     x += 1
    3     return x
    4 func1(5)     # 函数的执行命令,并且接受函数的返回值
    5 print(func1(5))   # 6
    再来看一个函数,该函数表示的是生成器函数:
     1 def func1(x):
     2     x += 1
     3     print(111)
     4     yield  x
     5     x += 2
     6     print(222)
     7     yield 'colin'
     8     x += 3
     9 g_obj = func1(5)  # 生成器函数对象
    10 print(g_obj)  # <generator object func1 at 0x000001B56D891F10>
    11 print(g_obj.__next__())   # 6
    12 print(g_obj.__next__())   # colin
    从上面分析可以知道,一个next对应一个yield
    yield 将值返回给 生成器对象.__next__()
    区别yield与return
    return 表示结束函数,给函数的执行者返回值
    yield 不会结束函数,一个next对应一个yield,给生成器对象.__next()返回值。

    生成器vs迭代器

    区别1:自定制区别
     1 l1 = [1,2,3,4,5]
     2 l1.__iter__()
     3 def func1(x):
     4     x += 1
     5     yield x
     6     x += 3
     7     yield x
     8     x += 5
     9     yield
    10 g1 = func1(5)
    11 print(g1.__next__()) # 6
    12 print(g1.__next__()) # 9
    13 print(g1.__next__()) # 无返回值 None

    区别2:内存级别的区别

    迭代器是需要可迭代对象进行转化,可迭代对象非常占内存
    生成器直接创建,不需要转化,从本质上就节省内存
    1 def func1():
    2     for i in range(1,10000):
    3         yield i
    4 g1 = func1()
    5 for i in range(50):
    6     print(g1.__next__()) # 每next一次,就取一个值

    区别:next() 与 send()

     1 def func1():
     2     print(1)
     3     count = yield 6
     4     print(count)
     5     print(2)
     6     count1 = yield 7
     7     print(count1)
     8     print(3)
     9     yield 8
    10 g = func1()
    11 next(g)
    12 g.send('colin')
    13 g.send('Jenny')
    14 g.send('taibai')
    从上面的例子可以看出,send 与next一样,也是对生成器取值(执行一个yield)的方法
    send可以给上一个yield传值
    第一次取值永远都是next
    最后一个yield永远也得不到send传的值
    函数直接取完所有值,所有值都直接放进内存处理
    1 def cloth1(n):
    2     for i in range(n+1):
    3         print('衣服%s号' % i)
    4 cloth1(10000)
    生成器函数:next多少次,就取多少次值,非常节省内存.
    1 def cloth2(n):
    2     for i in range(1,n+1):
    3         yield '衣服%s号' % i
    4 g = cloth2(10000)
    5 for i in range(50):
    6     print(g.__next__())
    7 for i in range(50):
    8     print(g.__next__())

    列表推导式

    先看一个for循环例子:
    1 l1 = []
    2 for num in range(1, 101):
    3     l1.append(num)
    4 print(l1)
    再来看一个例子:
    l = [i for i in range(1,101)]
    print(l)
    又比如下面的例子:
    1 l2 = ['python%s期' % i for i in range(1,16)]
    2 print(l2)
    3 print([i*i for i in range(1,11)])
    从上面的例子中,我们可以看出,只需要一行代码就几乎可以搞定你需要的任何的列表。所以,我们称该形式为列表推导式。
    第一种为循环模式,其形式为:
    [变量(加工后的变量) for 变量 in iterable]

     接下来一种方式为:筛选模式,该方式表示为:

     [变量(加工后的变量) for 变量 in iterable if 条件]
    l3 = [i for i in range(1,31) if i % 2 == 0]
    print(l3)
    print([i for i in range(1,31) if i % 3 == 0])
    print([i**2 for i in range(1,31) if i % 3 == 0])
    1 names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
    2          ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
    3 print([j for i in names for j in i if j.count('e') == 2])
    列表推导式的优缺点:
    优点:一行解决,方便
    缺点:容易着迷,不易不易排错,不能超过三次循环。
    但是,列表推导式不能解决所有列表的问题,所以不用太刻意用。
    生成器表达式:将列表推导式的[]换成()即可。
    1 g = (i for i in range(100000000000))
    2 print(g)
    3 print(g.__next__())
    4 print(g.__next__())
    5 print(g.__next__())
    6 print(g.__next__())
    7 print(g.__next__())
    8 print(g.__next__())

    字典:

    1 mcase = {'a': 10, 'b': 34}
    2 mcase_frequency = {mcase[k]: k for k in mcase}
    3 print(mcase_frequency)

    集合:

    1 squared = {x**2 for x in [1, -1, 2]}
    2 print(squared)
  • 相关阅读:
    Iterable,Iterator和forEach
    集合的线程安全性
    Servlet生命周期
    JavaWeb应用的生命周期
    将博客搬至CSDN
    (五)新类库的构件
    Python input和print函数
    python----调试
    Excel决定吃什么
    MATLAB—地图
  • 原文地址:https://www.cnblogs.com/colin1314/p/9506612.html
Copyright © 2011-2022 走看看