【问题标题】:Dividing the first element of a list by the second and the third by the fourth and so on将列表的第一个元素除以第二个元素,将第三个元素除以第四个元素,依此类推
【发布时间】:2014-12-15 17:22:29
【问题描述】:

目前我有 2 个相互划分的列表

a = [5,6,7,8]
b = [100,200,300,400]
output = [b/m for b,m in zip(a,b)]

但是,由于我的数据库的性质,以不同方式检索列表 ab 会更快:

data = [5,100,6,200,7,300,8,400]

列表中的第一个值是a 中的第一个值,第二个值是b 中的第一个值,第三个值是a 中的第二个值,依此类推。

output = [5/100,6/200,7/300,8/400]

因此,我需要将第一个值除以第二个值,将第三个值除以第四个值,依此类推。现在这没问题,但我需要它尽可能快。有什么建议吗?

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

    您可以为此使用切片:

    output = [b / m for b, m in zip(data[::2], data[1::2])]
    

    编辑 3: 我们现在拥有的 (len(data) = 8000):

    1. Jon Clements 的 iter 解决方案,耗时约 1 毫秒
    2. 1.1ms的正常切片方案
    3. range 解决方案只需 2.5 毫秒
    4. map 解决方案(使用 list 实现它)只需 2.7 毫秒

    【讨论】:

    • 您能解释一下它是如何工作的吗?还有关于 data[::2], data[1::2])
    • 这里已经有一个很好的答案来解释切片语法:stackoverflow.com/questions/509211/…
    • 不确定它是否更快 - 但它会节省创建新切片:[a / b for a, b in zip(*[iter(data)]*2)]
    • 它实际上还要快一点,大约 1ms vs 1.1ms ;)
    • 使用地图而不是列表推导可以提高性能。见下文:)
    【解决方案2】:
    >>> data = [5,100,6,200,7,300,8,400]
    >>> [data[i]/float(data[i+1]) for i in range(0,len(data),2)]
    [0.05, 0.03, 0.023333333333333334, 0.02]
    

    for i in range(0,len(data),2) 生成 0,2,4,6。因此data[i]/data[i+1] 给出data[0]/data[1],...,data[6]/data[7]

    【讨论】:

    • 这个问题在 Python 3 上是明确的,这意味着 a / bfloat 即使对于 ab 整数。
    • 另外(正如预期的那样,由于随机访问)这在我的机器上比切片方法慢 5 倍。删除显式 float 转换会导致 2.4 倍。
    • 哦!我没有看到python-3 标签。更新了我的解决方案。
    【解决方案3】:

    我更喜欢用 zip 和 map 来做这种事情,这样就可以在一行中完成:

    map(lambda x : x[0]/x[1], zip(a,b))
    

    zip 是一个生成元组列表的函数,如下所示:

    >>>>zip(a,b)
    [(5, 100), (6, 200), (7, 300), (8, 400)]
    

    并且 map 返回一个将给定函数应用于整行的新列表。我看到其他人报告说这需要几毫秒。将此应用于您的问题并使用上面在 IPython 中给出的列表切片:

    %timeit map(lambda x : x[0]/x[1], zip(data[::2], data[1::2]))
    1000000 loops, best of 3: 1.33 µs per loop
    

    编辑:使用 len(data) = 10000,我得到了 849 微秒;使用 8000,我得到 685 微秒。

    【讨论】:

    • 在 python 3.x 中 - 因为这是被标记的 - 它会是即时的...... OP 需要具体化到一个列表 - 无论如何,而不是使用 lambda,你是最好使用map(operator.div, ...) (另外 - 将您的时间与另一个帖子的时间进行比较有点像苹果和梨,因为您可能没有同时使用具有相同工作平衡的相同硬件等......)
    • 我还怀疑 1.33us 是因为您使用 3.x 获得了 iPython(而您的 map 示例暗示 2.x)并且它正在生成一个生成器(非常非常快),而不是实现任何东西......因此测试只是生成生成器的速度......不产生任何结果
    猜你喜欢
    • 2022-11-16
    • 2018-06-12
    • 1970-01-01
    • 2019-05-10
    • 2022-12-07
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多