我在 Codeeval 问题中使用了以下两种方法,我最初使用第一种方法,并认为我可以通过删除从列表到 lambda 的字符串到整数的转换来加快速度,但它实际上大大减慢了代码速度,为什么这样吗?
with open("multiply.txt") as f:
for line in f:
line1 = line[:line.find("|")].split()
line2 = line[line.find("|")+1:].split()
line1_int = [int(x) for x in line1 ]
line2_int = [int(x) for x in line2]
mult= map(lambda x, y: x*y, line1_int, line2_int)
print " ".join(str(s) for s in mult)
with open("multiply.txt") as f:
for line in f:
line1 = line[:line.find("|")].split()
line2 = line[line.find("|")+1:].split()
mult= map(lambda x, y: int(x)* int(y), line1, line2)
print " ".join(str(s) for s in mult)
最佳答案
在列表推导式中,int
被查找一次,它所绑定(bind)的代码对象可用于列表的每个元素。 lambda 表达式创建一个函数对象,每次调用时都需要在其中查找 int
,因为作为非本地名称,它可能在调用之间被反弹。
类似于
lambda x, y, i=int: i(x) * i(y), line1, line2
应该更快,因为 i
现在是调用函数时的局部变量查找,而不是 int
所需的全局查找。
更新:Python 2.7 中的一些快速计时测试:
# Using lists of integers
% python -m timeit -n 100 -s 'list1=range(10); list2=range(10)' \
'map(lambda x,y: x*y, list1, list2)'
100 loops, best of 3: 2.13 usec per loop
# Convert str to int at multiplication time
% python -m timeit -n 100 -s 'list1=map(str,range(10)); list2=map(str,range(10))' \
'map(lambda x,y: int(x)*int(y), list1, list2)'
100 loops, best of 3: 19 usec per loop
# Convert str to int, using localized int function
% python -m timeit -n 100 -s 'list1=map(str,range(10)); list2=map(str,range(10))' \
'map(lambda x,y,i=int: i(x)*i(y), list1, list2)'
100 loops, best of 3: 14.2 usec per loop
请注意,我的第一个测试不需要将字符串列表转换为整数作为测试的一部分,以隔离 map
调用中名称查找的影响。需要这样做会减慢第一个测试的速度。为了进行比较,这里有一个测试,它在调用 map
之前确实需要时间将字符串列表转换为整数列表:
% python -m timeit -n 100 -s 'list1=map(str,range(10)); list2=map(str,range(10))' \
'list1=[int(x) for x in list1]; list2=[int(x) for x in list2]; map(lambda x,y: int(x)*int(y), list1, list2)'
100 loops, best of 3: 9.77 usec per loop
速度较慢,但仍比在 lambda
内调用 int
更快。
关于python - 为什么在 lambda 函数中将字符串转换为整数比使用列表理解进行转换要慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21892838/