为什么在映射周围包装list()会导致函数运行



我试图解决的问题是在多线程庄园中映射函数列表。这些函数既打印出内容,又有返回值。这些返回值中的每一个都将存储在一个列表中。这是代码。。。

 import threading
 import time
 def PauseAndPrint1Seconds(num):
    time.sleep(1)
    print("Finished Pausing" + num)
    return [1]
 def PauseAndPrint2Seconds(num):
    time.sleep(2)
    print("Finished Pausing" + num)
    return [2, 2]
 def PauseAndPrint3Seconds(num):
    time.sleep(3)
    print("Finished Pausing" + num)
    return [3, 3, 3]
 def PauseAndPrint4Seconds(num):
    time.sleep(4)
    print("Finished Pausing" + num)
    return [4, 4, 4, 4]

 myfuncs = [PauseAndPrint1Seconds, PauseAndPrint2Seconds, PauseAndPrint3Seconds, PauseAndPrint4Seconds]
 result = [None] * len(myfuncs)
 def wrapFunc(i, num):
    result[i] = myfuncs[i](num)
 mythreads = [threading.Thread(target=wrapFunc, args = (i, " 12345")) for i in range(len(myfuncs))]
 map(lambda x: x.start(), mythreads)
 map(lambda x: x.join(), mythreads)

线程从未启动,我把它拿回来了。。。

 >>> map(lambda x: x.start(), mythreads)
 <map object at 0x7fd1a551b3c8>

 >>> result
 [None, None, None, None]

如果我把映射函数改为简单的循环,它似乎可以工作

>>> for x in mythreads:
...     x.start()
Finished Pausing 12345
Finished Pausing 12345
Finished Pausing 12345
Finished Pausing 12345
>>> result
[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4]]

同样奇怪的是,如果我用list()调用包装映射,那么不起作用的确切映射函数确实会起作用。

 >>> list(map(lambda x: x.start(), mythreads))
 [None, None, None, None]
 Finished Pausing 12345
 Finished Pausing 12345
 Finished Pausing 12345
 Finished Pausing 12345
 >>> result
 [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4]]

一些总结。。。1.我是Python的新手,如果我错过了一些基本的东西,我很抱歉2.我知道有一种更简单的方法。这是一个需要我理解的问题。

这是Python 2和Python 3之间的区别。

Python3返回一个地图对象,它可以记住需要做什么(就像生成器一样),但在你要求结果之前不会做任何工作(根据地图对象的结果创建列表就是一次要求所有结果)

Python2中的map已经返回了一个列表,因此与Python3 中的list(map(...))类似

仅仅为了副作用而使用地图或列表理解通常不被认为是Python的。如果你只是使用了一个for循环,那么事情何时发生就没有歧义了

for x in mythreads:
    x.start()

映射函数返回生成器。这意味着,当你试图得到结果时,它会调用函数,就像你做的那样:list(map(..))

最新更新