我刚刚在代码上运行了2to3,看起来像这样(A):
def idict(n):
return dict(zip(range(n), range(n)))
它生成了这个(B):
def idict(n):
return dict(list(zip(list(range(n)), list(range(n)))))
dict
和zip
都可以使用迭代器,为什么会这样翻译?
python -m timeit -s "import B as t" "t.idict(10)"
具有以下结果:
________________A______B______C___
Python 2.7.13 2.89 3.82 2.29
Python 3.5.1 2.63 4.34 A
即。从2.89 usec到4.34(+ 50%),默认翻译。
问题..(i)我不应该使用Python 3中的原始代码吗? (它产生了正确的结果,对我来说似乎是合理的); (ii)是2to3正确的工具(我们需要在转换~150KLOC的python时运行2和3)
更新:我在表格中添加了dict(itertools.izip(xrange(n), xrange(n)))
作为算法C.
答案 0 :(得分:4)
py2to3没有看到全局图片。它只是创建了一些等效代码,通过添加list
包装来替换现在不再创建列表的函数,以确保:
(它还将括号放在print
附近,......但这里不相关)
因此它会尝试让您的代码运行,但无法保证性能,例如 。
在您的示例中,列表包装器没用,因为dict
使用了迭代器。
因此,此工具对于使代码快速运行非常有用,但如果不与原始代码进行比较并决定要保留哪些代码或要更改的内容,则不应使用此工具。
该工具可能会改进为:
在你的情况下
dict(zip(range(n), range(n)))
非常好,并且在python 3中比在python 2中运行得更快,因为它避免了中间列表创建,所以保持这种方式。
相当于它的python 2会稍微复杂一些:
dict(itertools.izip(xrange(n), xrange(n)))
我的建议是你有很多代码需要翻译(我去过那里):
python -3
开关与python 2解释器公开你的代码并得到一些警告,而不是让它在python 3中崩溃(好吧,它应该警告Python 3x不兼容,2to3不能轻易修复,但它错过了很多的案例,好吧,它总比没有好,例如它找到了臭名昭着的has_key
电话)py2to3
并将结果与原始代码进行比较,手动决定应用更改的位置iteritems
,替换为items
xrange
,替换为range
dict.has_key
来电,unicode
内置-3
选项是不可见的,就像你使用二进制模式读取文本文件一样