python之生成器和列表推导式

一、生成器函数
1、生成器:就是自己用python代码写的迭代器,生成器的本质就是迭代器(所以自带了__iter__方法和__next__方法,不需要我们去实现)。
2、用以下两种方式构建一个生成器:
1,生成器函数:跟常规函数定义类似,但是,使用yield语句而不是return语句返回结果。
yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次从它离开的地方继续执行。

2,生成器表达式:类似于列表推导,但是,返回的是生成器的一个对象,
而不是一次构建一个结果列表。

3、生成器函数
3-1、先看一般的函数:

def func1(x):
    x += 1
    return x
func1(5) #函数的执行命令,并且接收函数的返回值。
print(func1(5))  #6

3-2、再看生成器函数:

def func1(x):
    x += 1
    print(666)
    yield x
    x +=2
    print(777)
    print(x)
    yield ‘xiaobai‘
    x +=3

g = func1(5)        # 此时的func1(5)不会执行函数,因为它只是生成器函数对象
print(g)            # <generator object func1 at 0x0000025E5D618780>
print(g.__next__()) #666 6
print(next(g))      #777 8 xiaobai

3-3、yield与return的区别:
return:结束函数,给函数的执行者返回值
yield:不会结束函数,一个next对应一个yield,
执行yield上面的代码并给 生成器对象.__next__() 返回值

3-4、生成器函数与迭代器的区别
区别1:自定制的区别
迭代器由可迭代对象转化而来,已经‘写死了’

l1 = [1,2,3,4,5]
l1.__iter__()

生成器可用自定制函数来定制

def func1(x):
    x += 1
    yield x
    x += 3
    yield x
    x += 5
    yield x
g1 = func1(5)
print(g1.__next__())
print(g1.__next__())
print(g1.__next__())

区别2:内存级别的区别。
迭代器是需要可迭代对象进行转化,可迭代对象非常占内存。
生成器直接创建,不需要转化,从本质就节省内存。

def func1():
    for i in range(1000000):
        yield i
g1 = func1()
for i in range(50):
    print(g1.__next__()) #一个next取一次值,可用for循环取值

3-5、send与next
先看例子:

def func1():
    print(1)
    count = yield 6

    print(count)
    print(2)
    count1 = yield 7

    print(count1)
    print(3)
    yield 8

g = func1()
print(g.__next__())       #1 6
print(g.send(‘xiaobai‘))  #xiaobai 2 7
print(g.send(‘xiaigou‘))  #xiaogou 3 8

总结:
send与next一样,也是对生成器取值(执行一个yield)的方法。
send可以给上一个yield 传值。
注意小坑:
1,第一次取值只能用next
2,最后一个yield不可能得到send传的值

3-6、生成器close()方法:

def fun():
    for i in range(5):
        yield i
g = fun()
print(g.__next__())
print(g.__next__())
print(g.__next__())
g.close() # 直接把生成器的值取(删)完了,后面就不能再取值
print(g.__next__()) # 报错

a = (i for i in range(4))
print(a.__next__())
print(a.__next__())
a.close()
print(a.__next__()) #报错

3-7、生成器函数的应用例子
要制作一批量很大的衣服,用普通的函数只能一次全部制作完:

def cloth1(n):
    for i in range(n+1):
        print(‘衣服%s号‘ % i)
cloth1(100000)  #一次全部制作完了

而用生成器函数,需要制作多少就先制作多少:

def cloth2(n):
    for i in range(1,n+1):
        yield ‘衣服%s号‘ % i
g = cloth2(10000)

先制作50件:
for i in range(50):
    print(g.__next__()) #衣服1号,衣服2号,衣服3号...衣服50号

再制作50件:
for i in range(50):
    print(g.__next__()) #衣服51号,衣服52号,衣服53号...衣服100号

二、列表推导式,生成器表达式
1、普通方法创建一个元素为1到100的列表:

l1 = []
for num in range(1,101):
    l1.append(num)
print(l1)

2、列表推导式:一行代码几乎搞定你需要的任何的列表。
2-1、两种方式:
  循环模式
  筛选模式

2-2、循环模式:[变量(加工后的变量) for 变量 in iterable]

#1到100的列表
l = [i for i in range(1,101)]
print(l) #[1,2,3,4...100]

#python1到python15的列表
l2 = [‘python%s‘ % i for i in range(1,16)]
print(l2)  #[python1,python2,python3...python15,]

#1到10的平方
l3 = [i*i for i in range(1,11)]
print(l3) #[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

2-3、筛选模式 [变量(加工后的变量) for 变量 in iterable if 条件]

#30以内的偶数
l4 = [i for i in range(1,31) if i % 2 == 0]
print(l4) #[2, 4, 6, 8,10,...28, 30]

#30以内能被3整除的数
l5 = [i for i in range(1,31) if i % 3 == 0]
print(l5) #[3, 6, 9, 12, 15, 18, 21, 24, 27, 30]

#30以内能被3整除的数的平方
l6 = [i**2 for i in range(1,31) if i % 3 == 0]
print(l6) #[9, 36, 81, 144, 225, 324, 441, 576, 729, 900]

#找出列表中含有两个‘e‘的元素
names = [[‘Tom‘, ‘Billy‘, ‘Jefferson‘, ‘Andrew‘, ‘Wesley‘, ‘Steven‘, ‘Joe‘],
         [‘Alice‘, ‘Jill‘, ‘Ana‘, ‘Wendy‘, ‘Jennifer‘, ‘Sherry‘, ‘Eva‘]]
l7 = [j for i in names for j in i if j.count(‘e‘) == 2]
print(l7) #[‘Jefferson‘, ‘Wesley‘, ‘Steven‘, ‘Jennifer‘]

2-4、列表推导式优缺点
优点:一行解决,方便。
缺点:容易着迷,不易排错,不能超过三次循环。
列表推导式不能解决所有列表的问题,所以不要太刻意用。

3、生成器表达式:将列表推导式的[]换成()即可。

g = (i for i in range(100000000000))
print(g) #生成器表达式左边的变量g是生成器对象
print(g.__next__())  # 0
print(g.__next__())  # 1
print(g.__next__())  # 2

上面代码相当于:
def func():
    for i in range(100000000000):
        yield i
g = func()  #生成器对象
print(g.__next__())
print(g.__next__())
print(g.__next__())

4、扩展
4-1、字典推导式

# 例一:将一个字典的key和value对调
dic = {‘a‘: 10, ‘b‘: 34}
new_dic = {dic[k]: k for k in dic}
print(new_dic)
# 结果:
# {10: ‘a‘, 34: ‘b‘}

# 例二:合并大小写对应的value值,将k统一成小写
dic = {‘a‘: 10, ‘b‘: 34, ‘A‘: 7, ‘Z‘: 3}
new_dic = {k.lower():dic.get(k.lower(),0) + dic.get(k.upper(),0) for k in dic}
print(new_dic)
# 结果:
# {‘a‘: 17, ‘b‘: 34, ‘z‘: 3}

4-2、集合推导式

# 例一:计算列表中每个值的平方,自带去重功能
set1 = {x**2 for x in [1, -1, 2]}
print(set1)
# 结果:
# {1, 4}

4-3、集合推导式和字典推导式的区别

相同点:外层都是使用大括号{}
不同点:返回的形式是 key:values 形式的就是字典,返回的形式是 values1,values2...形式的是集合
# 集合推导式
set1 = {x**2 for x in (1, -1, 2)}
print(set1,type(set1))  # {1, 4} <class ‘set‘>

# 字典推导式
dic1 = {x**2:x for x in (1, -1, 2)}
print(dic1,type(dic1))  # {1: -1, 4: 2} <class ‘dict‘>

4-4、练习题

# 例1:  过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
l1 = [i.upper() for i in [‘asdf‘,‘a‘,‘b‘,‘qwe‘] if len(i) >= 3]
print(l1)
# 结果:
# [‘ASDF‘, ‘QWE‘]

# 例2:  求(x,y)其中x是0-5之间的偶数,y是0-5之间的奇数组成的元组列表
l2 = [(x,y) for x in range(6) if x % 2 ==0 for y in range(6) if y % 2 == 1]
print(l2)
# 结果:
# [(0, 1), (0, 3), (0, 5), (2, 1), (2, 3), (2, 5), (4, 1), (4, 3), (4, 5)]

# 例3:  求M中3,6,9组成的列表
M = [[1,2,3],[4,5,6,24,3],[7,8,9,12,9]]
l3 = [j for i in M for j in i for z in [3,6,9] if j / z == 1 ]
print(l3)
# 结果:
# [3, 6, 3, 9, 9]

原文地址:https://www.cnblogs.com/yidashi110/p/10092276.html

时间: 2024-11-05 23:37:26

python之生成器和列表推导式的相关文章

python基础-三元表达式/列表推导式/生成器表达式

1.三元表达式:如果成立返回if前的内容,如果不成立返回else的内容 name=input('姓名>>: ') res='SB' if name == 'alex' else 'NB' print(res) 2.列表推导式:l=['egg'+str(i) for i in range(1,11)] print(l) 3.生成器表达式: l=('egg'+str(i) for i in range(1,11) if i >6) for i in l: print(i) 原文地址:http

day5--装饰器函数的信息打印,迭代器,生成器,列表推导式,内置函数

本文档主要内容: 一 装饰器函数的信息打印 二 迭代器 三 生成器 四 生成器表达式和列表推导式 五 内置函数 一 装饰器函数的信息打印 一个函数一旦被装饰器给装饰后,这个函数的信息使用原来的命令打印的就是装饰器函数的信息了,如何做呢? from functools import wraps def logger(f): @wraps(f) def inner(*args, **kwargs): """ :param args: 函数名,密码 :param kwargs: 备

闭包,迭代器,生成器,列表推导式

1:函数名的应用   1, 函数名就是函数的内存地址.    2, 函数名可以作为变量.    3, 函数名可以作为函数的参数.    4, 函数名可以作为容器类类型的元素.    5,函数名可以当做函数的返回值. 2:globals() locals() globals() # 返回全局变量的一个字典. locals()  返回 当前位置 的局部变量的字典. 1 name = 'leiwenxuan' 2 def fun(): 3 a = 2 4 b = 3 5 6 print(globals

生成器、列表推导式和生成器表达式

生成器 生成器特点: 1. 生成器本质上迭代器 2. 生成器是自己用代码创建的 获取生成器的两种方式: 1. 生成器函数 2. 生成器表达式 yield 下面来看一个例子 1 def func(): 2 print(111) 3 yield 666 4 print(222) 5 yield 233333 6 7 8 ret = func() # 获取生成器 9 print(ret) # <generator object func at 0x000002B1E535B258> 10 print

python迭代器,生成器,列表生产式

目录 列表生成式 生成器 1.定义 2.作用 3.返回值 迭代器 1.特点 2.常见的迭代器 3.可迭代对象 列表生成式 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式. 例如: >>> [x * x for x in range(1, 11)] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 生成器 1.定义 一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如

生成器、列表推导式、生成器表达式

一. # def g_function(): # print(555) # ret1 = yield {1,3} # print(666) # g = g_function() # print(g.__next__()) # print(g.__next__()) # 一个 next 对应一个 yield , 生成器函数 ,只有一个yield 所以报错 def g_function(): print(555) ret1 = yield {1,3} print(ret1) print(666) y

Python的高级特性2:列表推导式和生成器

一.列表推导式 1.列表推导式是颇具python风格的一种写法.这种写法除了高效,也更简短. In [23]: ['i:el' for i,el in enumerate(["one","two","three"])] Out[23]: ['i:el', 'i:el', 'i:el'] enumerate是内建函数,可以让列表获得“下标”的属性.而如果不用列表推导式,上例需要这么写 In [24]: lst = ["one",

python 【迭代器 生成器 列表推导式】

python [迭代器  生成器  列表推导式] 一.迭代器 1.迭代器如何从列表.字典中取值的 index索引 ,key for循环凡是可以使用for循环取值的都是可迭代的可迭代协议 :内部含有__iter__方法的都是可迭代的迭代器协议 :内部含有__iter__方法和__next__方法的都是迭代器 print(dir([1,2,3])) lst_iter = [1,2,3].__iter__() print(lst_iter.__next__()) print(lst_iter.__ne

python(列表推导式和生成器表达式)

从母鸡下蛋的故事讲起 1 老母鸡 = ('鸡蛋%s'%i for i in range(10)) 2 print(老母鸡) 3 for 蛋 in 老母鸡: 4 print(蛋) 5 g = (i*i for i in range(10)) 6 for i in g: 7 print(i) ①把列表解析的[]换成()得到的就是生成器表达式 ②列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更加节省内存空间 ③Python不但使用迭代器协议,让for循环变得更加通用.大部分内置函数,