Python 2 vs 3:用map()替换列表理解?
考虑到以下测试:Python 2 vs 3:用map()替换列表理解?,python,performance,python-3.x,list-comprehension,map-function,Python,Performance,Python 3.x,List Comprehension,Map Function,考虑到以下测试: >>> import timeit >>> timeit.timeit("[x + 'abc' for x in ['x', 'y', 'z']]") >>> timeit.timeit("map(lambda x: x + 'abc', ['x', 'y', 'z'])") 使用Python 2.7和3.4(Debian 8/testing/jessie),我得到了以下数字: Python27 Python34 1.3s
>>> import timeit
>>> timeit.timeit("[x + 'abc' for x in ['x', 'y', 'z']]")
>>> timeit.timeit("map(lambda x: x + 'abc', ['x', 'y', 'z'])")
使用Python 2.7和3.4(Debian 8/testing/jessie),我得到了以下数字:
Python27 Python34
1.3s 0.5s map()
0.6s 0.9s list comprehension
使用Python3,Map得到了显著改进,列表理解能力受到了严重影响
问题:将代码从Python 2移植到Python 3时,是否建议将列表理解更改为map()?您的测试不正确。在Python3中,
map()
返回迭代器,而不是列表。实际上,您并没有在测试中进行迭代,只是测试迭代器的创建
您需要包含迭代,以查看哪种方法更快;您可以使用长度为0的collections.deque()
,这将在不生成新列表对象的情况下进行迭代:
import timeit
timeit.timeit("deque([x + 'abc' for x in ['x', 'y', 'z']], maxlen=0)",
'from collections import deque')
timeit.timeit("deque(map(lambda x: x + 'abc', ['x', 'y', 'z']), maxlen=0)",
'from collections import deque')
通过将deque()
应用于两者,您可以再次平衡分数
现在列出两种平台上的理解:
Python27 Python34
1.91s 2.00s map()
1.18s 1.85s list comprehension
你真的应该使用更大的输入列表来正确地测试差异;太多
Python3上的原因列表理解速度减慢是因为它们有自己适当的作用域,就像生成器表达式以及Python2和Python3上的dict和set理解一样
如果您的map函数完全是用C实现的(与lambda相反,lambda推回Python,map()
可能会赢:
在这里,通过为使用的每个对象调用
str.\uuuu add\uuuu
方法来避免回调用Python代码。您没有正确地进行测试。在Python 3中,map()
返回一个迭代器,而不是列表。您实际上没有在测试中进行迭代,只是测试迭代器的创建
您需要包含迭代以查看哪种方法更快;您可以使用长度为0的collections.deque()
,这将在不生成新列表对象的情况下进行迭代:
import timeit
timeit.timeit("deque([x + 'abc' for x in ['x', 'y', 'z']], maxlen=0)",
'from collections import deque')
timeit.timeit("deque(map(lambda x: x + 'abc', ['x', 'y', 'z']), maxlen=0)",
'from collections import deque')
通过将deque()
应用于两者,您可以再次平衡分数
现在列出两种平台上的理解:
Python27 Python34
1.91s 2.00s map()
1.18s 1.85s list comprehension
您真的应该使用更大的输入列表来正确地测试差异;太多
Python3上的原因列表理解速度减慢是因为它们有自己适当的作用域,就像生成器表达式以及Python2和Python3上的dict和set理解一样
如果您的map函数完全是用C实现的(与lambda相反,lambda推回Python,map()
可能会赢:
在这里,通过调用
str来避免调用Python代码。对于使用的每个对象,都要调用add\uuuu
方法。map
在3.x中不构建列表-因此这里的计时是苹果和苹果pears@MartijnPieters这里的OP似乎从来没有在3.x中实现他们的映射
。另一件会改变你的“时间”的事情是使用在3.x中,lambdas与使用name函数map
的比较并没有建立一个列表,所以这里的时间是苹果和苹果pears@MartijnPieters这里的OP似乎从未在3.x中实现它们的映射
。“timeit”的另一个改变是使用lambdas而不是使用name函数。感谢您的解释,非常有见地!比ks的解释,很有见地!