python⽣成1到100的列表_python列表⽣成式与列表⽣成器的
使⽤
列表⽣成式:会将所有的结果全部计算出来,把结果存放到内存中,如果列表中数据⽐较多,就会占⽤过多的内存空间,可能会导致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%2==0:
numbers.append(x)
print(numbers)
⽤列表⽣成式⽣成列表:
#for循环遍历0~101的数字,如果数字对2取余==0,表⽰是偶数,x放在列表中
numbers=[x for x in range(0,101)if x%2==0]
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()⽅法
使⽤循环对⽣成器对象进⾏遍历(推荐)
python生成1到100之间随机数
调⽤⽣成器对象的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' % sizeof(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' % sizeof(g2))
输出结果:
列表⽣成式返回结果花费的时间: 0.8215489387512207
列表⽣成式返回结果占⽤内存⼤⼩:81528056
⽣成器返回结果花费的时间: 0.0
⽣成器返回结果占⽤内存⼤⼩:88
可见,⽣成器返回结果的时间⼏乎为0,结果所占内存空间的⼤⼩相对于列表⽣成器来说也要⼩的多。以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持脚本之家。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论