自学内容网 自学内容网

Python学习 问题 day02(列表推导式、生成器推导式)

列表推导式

  • 列表推导式是一种 Python 构造,可减少生成新列表或过滤现有列表所需的代码行。列表推导式包含在方括号内,它由一个表达式、一个或多个 for 循环和一个用于过滤生成的列表的可选条件组成。
  • 列表推导式使用以下语法:
new_list = [expression(item) for item in iterable if condition]
  • 相当于以下写法
new_list = []
for item in iterable:
if condition:
new_list.append(expression(item))
  • 举例说明:
  • 从1到10,使用列表推导式的写法
numbers = [x for x in range(1,11)]
print(numbers)
>>> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  • 再将每个元素乘以2
numbers = [2*x for x in range(1,11)]
print(numbers)
>>> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
  • 从1到10,只要偶数
numbers = [x for x in range(1,11) if x%2==0]
print(numbers)
>>> [2, 4, 6, 8, 10]

  • 使用列表推导式,将嵌套列表进行平铺
>>> vec = [[1,2,3],[4,5,6],[7,8,9]]
>>> list = [num for elem in vec for num in elem]
>>> print(list)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
'''
在这个列表推导式中有两个循环,其中第一个循环为外循环,用来获取嵌套列表最外面的[]内的元素;
第二个循环为内循环,用来获取嵌套列表第二层[]内的元素。
'''
#用循环实现其等价写法:
vec = [[1,2,3],[4,5,6],[7,8,9]]
result= []
for elem in vec:
    for num in elem:
       result.append(num)
print(result)

  • 实现矩阵的转置,注意这里最外面的for,是用来获取嵌套列表最外面的[ ]内的元素,而里面的for才是获取嵌套列表第二层[ ]内的元素
matrix = [[1, 2, 3, 4],[5, 6, 7, 8],[9, 10, 11, 12]]
print("原矩阵:",matrix)
print("转置矩阵为:",[[row[i] for row in matrix] for i in range(4)])

生成器推导式

  • 从形式上看,生成器推导式与列表推导式非常接近,只是生成器推导式使用圆括号而不是列表推导式所使用的方括号。
  • 与列表推导式不同的是,生成器推导式的结果是一个生成器对象,而不是列表,也不是元祖。但使用生成器对象的元素时,可以根据需要将其根据需要转化为列表或者元祖。
  • 使用生成器推导式创建生成器对象,看起来使用生成器推导式时只不过将列表推导式的方括号改为圆括号即可
>>> g = ((i+2)**2 for i in range(10))
>>> g
<generator object <genexpr> at 0x000001CA569C5AC8>

  • 将创建好的生成器对象转换为列表或元组
>>> g = ((i+2)**2 for i in range(10))
>>> g
<generator object <genexpr> at 0x000001CA569C5AC8>
>>> list(g)#将生成器对象转化为列表
[4, 9, 16, 25, 36, 49, 64, 81, 100, 121]
>>> tuple(g)#将生成器对象转化为元祖
()#为什么是空的??!看下面总结

注:关于惰性求值
1.是什么:惰性求值(Lazy Evaluation),又译为惰性计算、懒惰求值,也称为传需求调用(call-by-need)。
2.为什么:使用惰性求值的目的是要最小化计算机要做的工作。eg:生成器推导式是继列表推导式后的Python推导式,比列表推导式速度快,占内存少。
3.特点:不管用什么方法访问元素,当所有元素访问结束后,立马清空生成器对象。如果需要重新访问其中的元素,必须重新创建该生成器对象。

  • 遍历生成器对象中的元素
>>> g = ((i+2)**2 for i in range(10))
>>> print(g.__next__())#使用生成器对象__next__()方法获取元素
4
>>> print(g.__next__())
9
>>> print(next(g))#使用内置函数next()方法获取生成器对象中的元素
16
>>> print(next(g))
25
#-----使用循环直接遍历生成器对象中的元素-------
g = ((i+2)**2 for i in range(10))
for item in g:
    print(item,end = ' ')

  • 使用yield关键字来创建生成器对象
    注:关于yield关键字
    1.yield作为Python33个关键字之一,在生成器函数中用来返回值。Python33个关键字
    2.可以把yield看做return,只不过return的作用是在程序中返回某个值,返回之后程序就不再往下运行了。而使用yield的函数是一个生成器,不仅仅是一个简单的函数。
    3.可以将yield理解为:暂停执行,需要时再产生一个新元素。也就是说,yield扮演的也是返回的角色,但并不意味着yield返回就结束了整个程序,仅仅是暂停,下次需要时再出现。
def f():
    a,b = 1,1#序列解包,同时为多个元素赋值
    while True:
        yield a#暂停执行,需要时再产生一个新元素
        a,b = b,a+b#序列解包,继续生成新元素
a = f()#创建生成器对象
for i in range(10):#斐波那契数列中前十个元素
    print(a.__next__(),end = ' ')
    #结果:1 1 2 3 5 8 13 21 34 55
for i in f():
    if i > 100:#斐波那契数列中第一个大于100的元素
        print(i)
        #结果:144
        break
a = f()
print(next(a))#使用内置函数next()获取生成器对象中的元素
print(next(a))#每次获取新元素时,由yield语句生成
print(next(a))
#结果:
1
1
2

参考文献

  1. Python 中的列表推导式
  2. Python列表推导式
  3. Python生成器推导式

原文地址:https://blog.csdn.net/u011453680/article/details/137559581

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!