佛山狮山网站建设,网站上的小动画咋做,制作企业网站的一般流程,深圳网站建设比较列表生成式#xff1a;会将所有的结果全部计算出来#xff0c;把结果存放到内存中#xff0c;如果列表中数据比较多#xff0c;就会占用过多的内存空间#xff0c;可能会导致MemoryError内存错误或者导致程序在运行时出现卡顿的情况
列表生成器#xff1a;会创建一个列表…列表生成式会将所有的结果全部计算出来把结果存放到内存中如果列表中数据比较多就会占用过多的内存空间可能会导致MemoryError内存错误或者导致程序在运行时出现卡顿的情况
列表生成器会创建一个列表生成器对象不会一次性的把所有结果都计算出来如果需要获取数据可以使用next()函数来获取但是需要注意一旦next()函数获取不到数据会导致出现StopIteration异常错误可以使用for循环遍历列表生成器获取所有数据
需要视情况而定如果数据量比较大推荐使用生成器
python2.7中就是range(生成式) 和 xrange(生成器)的区别
列表生成式是快速生成一个列表的一些公式
在列表中存放0~100的数
普通的列表生成
numbers[]
for x in range(0,101):
numbers.append(x)
print(numbers)
用列表生成式生成列表[要放入列表的数据 简单的表达式1 表达式2]
#x for x in range(0,101) for循环遍历出来的值放入列表中
numbers[x for x in range(0,101)]
print(numbers)
列表中存放0~100的偶数
普通方法生成列表
for x in range(0,101):
if x%20:
numbers.append(x)
print(numbers)
用列表生成式生成列表
#for循环遍历0~101的数字如果数字对2取余0表示是偶数x放在列表中
numbers[x for x in range(0,101)if x%20]
print(numbers)
找出列表list1[asd,adf,dafg,acbo]带有a的字符
普通写法
rs_list[]
for s in list1:
if a in s:
rs_list.append(s)
print(rs_list)
列表生成式
list2[x for x in list1 if a in x]
列表生成式支持双层for循环
list3[x*y for x in range(0,10) for y in range(20)]
print(list3)
生成器构造实例
# 使用类似列表生成式的方式构造生成器
g1 (2*n 1 for n in range(3, 6))
# 使用包含yield的函数构造生成器
def my_range(start, end):
for n in range(start, end):
yield 2*n 1
g2 my_range(3, 6)
print(type(g1))
print(type(g2))
输出结果生成器的调用方式
要调用生成器产生新的元素有两种方式
调用内置的next()方法
使用循环对生成器对象进行遍历推荐
调用生成器对象的send()方法
实例1使用next()方法遍历生成器
print(next(g1))
print(next(g1))
print(next(g1))
print(next(g1))
输出结果
7
9
11
Traceback (most recent call last):
File ***/generator.py, line 26, in
print(next(g1))
StopIteration
print(next(g2))
print(next(g2))
print(next(g2))
print(next(g2))
输出结果
7
9
11
Traceback (most recent call last):
File ***/generator.py, line 31, in
print(next(g2))
StopIteration
可见使用next()方法遍历生成器时最后是以抛出一个StopIeration异常终止。
实例2使用循环遍历生成器
for x in g1:
print(x)
for x in g2:
print(x)
两个循环的输出结果是一样的
7
9
11
可见使用循环遍历生成器时比较简洁且最后不会抛出一个StopIeration异常。因此使用循环的方式遍历生成器的方式才是被推荐的。
需要说明的是如果生成器函数有返回值要获取该返回值的话只能通过在一个while循环中不断的next()最后通过捕获StopIteration异常
实例3调用生成器对象的send()方法
def my_range(start, end):
for n in range(start, end):
ret yield 2*n 1
print(ret)
g3 my_range(3, 6)
print(g3.send(None))
print(g3.send(hello01))
print(g3.send(hello02))
输出结果
7
hello01
9
hello02
11
print(next(g3))
print(next(g3))
print(next(g3))
输出结果
7
None
9
None
11
结论
next()会调用yield但不给它传值
send()会调用yield也会给它传值该值将成为当前yield表达式的结果值
需要注意的是第一次调用生成器的send()方法时参数只能为None否则会抛出异常。当然也可以在调用send()方法之前先调用一次next()方法目的是让生成器先进入yield表达式。
生成器与列表生成式对比
既然通过列表生成式就可以直接创建一个新的list那么为什么还要有生成器存在呢
因为列表生成式是直接创建一个新的list它会一次性地把所有数据都存放到内存中这会存在以下几个问题
内存容量有限因此列表容量是有限的
当列表中的数据量很大时会占用大量的内存空间如果我们仅仅需要访问前面有限个元素时就会造成内存资源的极大浪费
当数据量很大时列表生成式的返回时间会很慢
而生成器中的元素是按照指定的算法推算出来的只有调用时才生成相应的数据。这样就不必一次性地把所有数据都生成从而节省了大量的内存空间这使得其生成的元素个数几乎是没有限制的并且操作的返回时间也是非常快速的仅仅是创建一个变量而已。
我们可以做个试验对比一下生成一个1000万个数字的列表分别看下用列表生成式和生成器时返回结果的时间和所占内存空间的大小
import time
import sys
time_start time.time()
g1 [x for x in range(10000000)]
time_end time.time()
print(列表生成式返回结果花费的时间 %s % (time_end - time_start))
print(列表生成式返回结果占用内存大小%s % sys.getsizeof(g1))
def my_range(start, end):
for x in range(start, end):
yield x
time_start time.time()
g2 my_range(0, 10000000)
time_end time.time()
print(生成器返回结果花费的时间 %s % (time_end - time_start))
print(生成器返回结果占用内存大小%s % sys.getsizeof(g2))
输出结果
列表生成式返回结果花费的时间 0.8215489387512207
列表生成式返回结果占用内存大小81528056
生成器返回结果花费的时间 0.0
生成器返回结果占用内存大小88
可见生成器返回结果的时间几乎为0结果所占内存空间的大小相对于列表生成器来说也要小的多。
以上就是本文的全部内容希望对大家的学习有所帮助也希望大家多多支持脚本之家。