2014-02-05 47 views
0

我有一個程序可以與Python 2.7但不是Python 3.3當然我知道我需要使用範圍而不是xrange,add()等等。但程序有很多'地圖'的方法,它似乎造成問題。當我得到這個錯誤:TypeError: object of type 'map' has no len()我只是鑄造它作爲一個字符串,它的工作。將Python 2.7語法轉換爲3.3 - sum(map(len,P))

我想不出什麼了如何轉換是這樣的表達: sum(map(len,P)) 我得到這個錯誤:TypeError: object of type 'map' has no len() 但這次我不知道該怎麼投,以及如何。 如果有幫助,我可以發佈整個代碼。

這是對P是如何被初始化:

P, Q = [line.strip().lstrip('(').rstrip(')').split(')(') for line in input_data.readlines()] 
P = [map(int, perm_cycle.split()) for perm_cycle in P] 
+0

你嘗試:http://docs.python.org/2/library/2to3.html – Chandan

+2

鬼。在Python 3.2.3中'sum(map(len,[range(3),range(4)]))'returns'7',所以你的問題並沒有提供我們需要的信息來重現問題。 – Alfe

+0

'P'等於什麼? –

回答

2

而不是

P = [map(int, perm_cycle.split()) for perm_cycle in P]' 

使用

P = [list(map(int, perm_cycle.split())) for perm_cycle in P]' 

問題就出現了,因爲你想以後這在Python 2的作品,但調用len(map(...))沒有在Python 3因爲Python 3評估該map懶洋洋地(它是一臺發電機)。在其周圍運行明確的list以消除懶惰並獲得真正的列表。

認爲你也許可以帶,其map完全因爲如果你只在列表的長度有興趣,就沒有必要map它在某種程度上。 map ping它不會改變它的大小。

這將意味着評估此:

sum(map(len, perm_cycle.split())) 

代替。

+0

完美!謝謝! :)) – FairyDuster

0

Python 3map返回迭代器,而在Python 2它返回一個列表。您可以通過調用list(iterator)從迭代器構造一個列表。

所以,你需要改變P設爲:

P = [list(map(int, perm_cycle.split())) for perm_cycle in P] 

然後P的元素可以傳遞給len

另一種方式來改變它是有表情是:

sum(len(list(item) for item in P) 

您可以隨時更換map呼叫與generator expression在Python 3(2你會用一個列表理解取代它) 。

+0

問題出在'P'上,所以應用'list'來得太遲。 – Alfe

+0

你是對的 - 更新迴應上面的評論。 – babbageclunk

1

可以的P每個元素轉換到一個列表第一:

map(lambda x: len(list(x)), P) 

或者:

map(len, map(list, P)) 

一個更好的辦法將遵循@Alfe答案。

下面是一個簡單的(雖然不是完美的)規則:在Python3中將Python2 map(...)替換爲list(map(...))

+0

+1,沒有意識到P的元素可能是一個列表。 – zhangxaochen

0

您可以強制map嚴格使用list(map)進行評估,因此len(map(len, P))或類似表達式在Python3中仍然有效。

基本上,

import sys 

if sys.version_info.major > 2: 
    import builtins 
    def map(f, *args): 
     return list(builtins.map(f, *args))