为什么在lambda函数中将字符串转换为int比使用list comprehension转换更慢

时间:2014-02-19 21:28:37

标签: python lambda list-comprehension

我在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)

2 个答案:

答案 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))