2014-02-11 112 views
11

我是Python新手。我使用Python 3.3.2,我有一個很難弄清楚爲什麼下面的代碼:使用map函數返回的列表在使用後消失

strList = ['1','2','3'] 
intList = map(int,strList) 
largest = max(intList) 
smallest = min(intList) 

給了我這個錯誤:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: min() arg is an empty sequence 

但是這個代碼:

strList = ['1','2','3'] 
intList = list(map(int,strList)) 
largest = max(intList) 
smallest = min(intList) 

給我沒有任何錯誤。

我的想法是,當intList被分配給映射函數的返回值時,它將成爲迭代器而不是列表,如the docs。也許作爲調用max()的副作用,迭代器已迭代到列表的末尾,導致Python相信列表是空的(我在這裏從C知識中繪製,我不熟悉迭代器如何真正工作。在Python)的唯一證據我要支持這個的是,對於第一個代碼塊:

>>> type(intList) 
<class 'map'> 

而對於第二個代碼塊:

>>> type(intList) 
<class 'list'> 

有人可以證實或否認這請給我?

回答

12

你完全正確。在Python 3中,map返回一個迭代器,您只能迭代一次。如果第二次迭代迭代器,它將立即引發StopIteration,就好像它是空的。 max消耗整個事情,min認爲迭代器爲空。如果您需要多次使用元素,則需要調用list來獲取列表而不是迭代器。

+0

你也可以調用tuple或設置地圖對象,如果它適合你的目的比列表更好 – fanny

5

map文檔:

Return an iterator that applies function to every item of iterable, yielding the results.

http://docs.python.org/3/library/stdtypes.html#typeiter

Once an iterator’s next() method raises StopIteration, it must continue to do so on subsequent calls.

因此,一個迭代器,不管底層數據對象的,只能使用一次。它建立在發電機的概念之上。

itertools.tee可以用來做一個多個獨立的迭代器。

l1,l2 = itertools.tee(intList,2) 
max(l1) 
min(l2)