我在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)
答案 0 :(得分:4)
在列表推导中,int
被一次查找,它所绑定的代码对象可用于列表的每个元素。 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
比在int
内调用lambda
更慢但速度更快。
答案 1 :(得分:1)
@chepner精美地回答了你的问题!我会花点时间进行一些代码审查。
with open('multiply.txt') as f:
for line in f:
line1,line2 = map(str.split,line.split("|"))
mult = [x*y for x,y in zip(map(int,line1),map(int,line2))]
print(' '.join(str(s) for s in mult))