2015-12-15 34 views
1

我試圖解決的問題是映射在多線程莊園中的函數列表。這些函數都打印出來並具有返回值。每個返回值都將存儲在一個列表中。下面是代碼...爲什麼包裹地圖的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.我知道還有一個更簡單的方法來做到這一點。這是我理解的問題。

+5

地圖是懶惰的 - 它們只在需要時才產生每個元素。通過調用'list(your_map)',你強制地圖產生所有元素立即放入列表,這意味着調用'mythreads'每個元素的映射函數。如果你想要實現「類似地圖」的結果,可以考慮使用列表解析:'[x.start()for mythreads]'等等。 – senshin

+0

如果你使用的是Python 3,'map()'函數不會返回一個'list',而是一個'iterator'。 –

+1

讓標準庫爲您做好工作。 'multiprocessing.pool.ThreadPool'類管理線程,並有一個'map'方法將處理擴展到線程之間。 – tdelaney

回答

4

這是Python2和Python3的區別。

Python3返回一個地圖對象,它記住需要完成的事情(比如生成器),但直到詢問結果才做任何工作(根據地圖對象的結果創建一個列表請求它們一次全部)

map在Python2已經返回一個列表,所以在Python3

它一般不考慮Python的使用地圖或列表內涵只是爲了其副作用類似list(map(...))。如果你只是使用了for循環,沒有什麼時候事情發生

for x in mythreads: 
    x.start() 
0

映射函數返回發生器歧義。這意味着,當您嘗試獲得結果時,它會調用該函數,如下所示:list(map(..))

相關問題