【问题标题】:Performing bulk arithmetic operations on python list在 python 列表上执行批量算术运算
【发布时间】:2018-01-09 10:50:01
【问题描述】:

我有一个整数列表,我想对列表切片(子数组)的每个元素或某些索引(例如 range(start, end, jump) )高效地执行加法、乘法、下除法等操作。与列表切片的每个元素相加或相乘的数字是常数(比如“k”)。

例如:

    nums = [23, 44, 65, 78, 87, 11, 33, 44, 3]
    for i in range(2, 7, 2):
        nums[i] //= 2 # here 2 is the constant 'k'
    print(nums)
    >>>    [23, 44, 32, 78, 43, 11, 16, 44, 3]

我必须在不同的切片/范围内多次执行这些操作,并且常数“k”因不同的切片/范围而异。显而易见的方法是运行一个 for 循环并修改元素的值,但这还不够快。您可以通过使用 numpy 数组有效地做到这一点,因为它支持批量分配/修改,但我正在寻找一种在纯 python 中执行此操作的方法。

【问题讨论】:

  • 足够快有多快? nums在现实中有多大或者有多少操作?我认为您当前的代码非常有效
  • 使用numpy有什么问题?
  • 任何表现出显着性能提升 (> 20%) 的东西对我来说都足够快。我的整数列表中有 100 万个元素,我必须修改表单范围(开始、结束、开始)索引处的值。
  • 看起来你想让 nums 的范围更大。如果不是,则尝试过的代码看起来还可以。 numpy 有高效的特性,你也可以考虑一下
  • 您可能已经在纯 Python 中找到了最有效的方法。你听说过Cython吗?这是一个选择吗?

标签: python python-3.x optimization


【解决方案1】:

避免for循环的一种方法如下:

>>> nums = [23, 44, 65, 78, 87, 11, 33, 44, 3]
>>> nums[2:7:2] = [x//2 for x in nums[2:7:2]]
>>> nums
[23, 44, 32, 78, 43, 11, 16, 44, 3]

【讨论】:

  • 您并没有避免 for 循环,您只是在使用列表理解并制作不必要的列表切片副本。这比我的代码效率还要低。
  • 你是对的。使用 timeit.timeit 和一个大数组,大约需要两倍的时间。这让我很吃惊,因为列表推导直到列表建立后才会返回到用户级代码。我希望这会更有效率。你每天都会学到新东西:-)
猜你喜欢
  • 1970-01-01
  • 2013-09-06
  • 1970-01-01
  • 2020-07-13
  • 1970-01-01
  • 2014-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多