# -*- coding: utf-8 -*- from multiprocessing import Pool import os, time, random def worker(msg, ip): t_start = time.time() print("%s 开始执行, ip:%s, 进程号为%d" % (msg['id'], ip['ip'], os.getpid())) time.sleep(random.random() * 2) # time.sleep(2) t_stop = time.time() print(msg['id'], "执行完毕, ip:%s, 耗时%0.2f" % (ip['ip'], t_stop - t_start)) def start(d): po = Pool(10) a_list = [ {"ip": "ip - 1"}, {"ip": "ip - 2"} ] d_list = d for_times = 0 while len(d_list) > 0: print("第 %s 次" % (for_times)) x = 0 for i in d_list: if x < 2: po.apply_async(worker, (i, a_list[for_times])) d_list.pop(x) x+=1 else: print("==============") break for_times += 1 print("----start----") po.close() po.join() print("----end----") if __name__ == '__main__': d = [{ "id": 1, "keyword": "site:www.aaa.com 灯", "site": "www.aaa.com" }, { "id": 2, "keyword": "site:www.bbb.com 灯", "site": "www.bbb.com" }, { "id": 3, "keyword": "site:www.ccc.com 灯", "site": "www.ccc.com" }, { "id": 4, "keyword": "site:www.ddd.com 灯", "site": "www.ddd.com" }] start(d)
这段代码没问题。可是会报错;我 debug 了。就是 for 里面的 if 的问题。
理论上 whlie 两次就结束了。可是为啥这里 whlie 走了三次呢?
while 第二次的时候,会看到 for 里面的 if 没生效了。
这是不是 python 的 bug ?
我已经排两天。无结果。
1 GrayXu 2020-04-18 16:21:28 +08:00 没看代码…但觉得是 python 的 bug ? |
2 yingo 2020-04-18 16:24:38 +08:00 |
3 renmu 2020-04-18 16:28:45 +08:00 via Android 不要一边对列表修改一边进行判断,会引起奇怪的问题。想复制的话可以采用 list.copy(),而不是直接等于 |
![]() | 4 NeinChn 2020-04-18 16:29:37 +08:00 d_list.pop(x)是咋想的。。。 |
![]() | 5 xiri 2020-04-18 16:30:00 +08:00 调试看了一下,没问题啊,最后是数组越界了,主要就是你在 for 循环里面弹出 d_list 中的元素导致的,你自己去看看每次循环的时候 d_list 变成啥样了,i 是啥就知道了,还有,最好不要写下面这样的代码,出问题能让你头痛死 for i in d_list: ...... d_list.pop(x) ...... |
![]() | 6 DGideas 2020-04-18 16:32:02 +08:00 你的程序的输出结果是什么? 贴代码到这里来问问题,没有描述解释器和操作系统环境,别人复现你的问题也不一定准啊 |
7 Jirajine 2020-04-18 16:32:19 +08:00 via Android 你在迭代时修改了迭代对象本身,当然会产生难以预料的行为。 一个简单的做法是在目标对象的复制上迭代, 将 for i in d_list: 修改为 for i in list(d_list): |
![]() | 8 wysnylc 2020-04-18 16:32:42 +08:00 人类总是觉得机器有问题而不是自己有问题 |
9 yingxiangyu 2020-04-18 16:36:48 +08:00 循环过程中不要修改循环的列表,你 pop 了列表就变了,第二次循环开始是 2 元素,pop 一个变 1 元素,这个 for 还要不要接着执行 |
![]() | 10 imn1 2020-04-18 16:41:19 +08:00 看标题还没看正文就想,是不是又是增减列表的问题 进来一看果然…… |
![]() | 11 metamask 2020-04-18 16:43:40 +08:00 首先这标题就够标题了 import 的时候,这样写是好的 import os import random import time 然后 都用到 py3 了,多用用 f,或者 format 要随机 1-2s 直接用 random.uniform(0, 2) while 嵌套 for 这种也挺不好看的 不需要特殊判断的话 while d_list 就可以了 需要判断第 N 次的话,直接用 for index, value in enumerate(d_list) 不要一边遍历 list 一般修改 ============== 所以不要搞个大新闻 |
12 superrichman 2020-04-18 16:46:51 +08:00 d_list.pop(x) 问题出在这里,仔细琢磨一下你要 pop 出来的元素和下标为 x 的是不是同一个。 |
![]() | 13 smallgoogle OP |
14 cassidyhere 2020-04-18 19:49:15 +08:00 用队列。。。 |
15 ifzzzh 2020-04-18 22:13:51 +08:00 @smallgoogle #13 你都用 x<2 做判断了为什么不直接拿 x 做循环变量呢 |