现象:写了个参数 args = (x*x for x in range(1, 11)),写了个while True循环调用进程池,采用该参数,跑第二遍时进程不跑......
def unzip(args):
print(args)
time.sleep(20)
def process_retry (processes, args, func):
attemps = 1
data = []
while True:
try:
pool = Pool(processes)
result = pool.map_async(func, args)
pool.close()
data = result.get(timeout=10)
except TimeoutError:
pool.terminate()
if __name__ == '__main__':
args = ((i) for i in range(5))
tar_out = process_retry(4, args, unzip)
列表生成式和参数生成器剖析
1、列表生成式
test_list = [x*x for x in range(1, 11)]
print(test_list )
结果:[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
列表test_list 所有的值都存在内存中。在python中,list,tuple,dict和set都是可迭代的对象,字符串也是可迭代对象。
2、生成器(generator)
引题:通过上文列表生成式,可以直接创建一个列表。受到内存限制,列表容量肯定是有限的;例如创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果仅需要访问前面几个元素,后面绝大多数元素占用的空间都浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
生成器语法:要创建一个generator,有很多种方法。第一种方法很简单,只要把上文中列表生成式的 [ ] 改成 ( ) ,就创建了一个generator:
generator = (x*x for x in range(1, 11))
print(generator)
结果:<generator object <genexpr> at 0x0000017AAA0CE510>
可以看出,我们并不能直接访问到生成器的值,上文可以直接打印出列表test_list的每一个元素,而generator的每一个元素可以通过next()函数获得generator的下一个返回值;
# 接上文代码
print(next(generator))
print(next(generator))
print("*"*10)
for i in generator:
print(i)
结果:
1
4
**********
9
16
25
36
49
64
81
100
需注意:生成器只能使用一次for循环来遍历,之后就不能使用了
# 接上文代码
print("&"*10)
print(next(generator))
结果:
Traceback (most recent call last):
File "xxx/text.py", line 91, in <module>
print(next(generator))
StopIteration
&&&&&&&&&&
Process finished with exit code 1
生成器不会把结果保存在一个系列中,而是保存生成器的状态,在每次进行迭代时返回一个值,直到遇到StopIteration异常结束。
总结生成器特点:
1.可迭代
2.只能读取一次
3.实时生成数据,不全存在内存中
参考链接:https://blog.csdn.net/qq_43503724/article/details/85724419