为了账号安全,请及时绑定邮箱和手机立即绑定

Python:检查 2 个列表是否一起增加的任何优化方法?

Python:检查 2 个列表是否一起增加的任何优化方法?

慕婉清6462132 2021-08-17 16:38:00
假设我们有 2 个列表a = [1,2,4,3,5]和b = [103,122,800,500,1000]有没有一种优化的方法可以检查它们是否“一起增加”?我当前的解决方案采用循环:for i in range(1,len(a)):   if (a[i-1] < a[i] and b[i-1] > b[i]) or (a[i-1] > a[i] and b[i-1] < b[i]):       print('wrong')有没有更好的办法?笔记:解决方案不需要特定于列表(实际上任何数据结构都可以)两个迭代器不需要增加相同的单位数,只需一起增加即可。
查看完整描述

3 回答

?
婷婷同学_

TA贡献1844条经验 获得超8个赞

你真的不能得到任何比O(n)的速度更快,但你可以让你的代码有点用较短,也许更容易阅读numpy.diff和比较sign的差异文件,a并且b:


>>> from numpy import diff, sign

>>> a, b = [1,2,4,3,5], [103,122,800,500,1000]

>>> sign(diff(a))

array([ 1,  1, -1,  1])

>>> all(sign(diff(a)) == sign(diff(b)))

True

>>> a, b = [1,2,4,3,5], [103,122,800,500,100]

>>> all(sign(diff(a)) == sign(diff(b)))

False

这种解决方案的缺点是,它不使用懒惰评价,即它计算和整个比较sign(diff(...))阵列即使的“increasingness”a和b不同之处在于非常第一位置。如果列表很长,您应该考虑使用另一种方法。


查看完整回答
反对 回复 2021-08-17
?
慕妹3242003

TA贡献1824条经验 获得超6个赞

就 O(order notation) 而言,假设列表没有顺序,你不能比线性更好。但是,您可以使用诸如 cython、numba 之类的 Python 编译器来加速您的代码。您使用numba 的代码:


import numpy as np

import numba as nb


@nb.njit()

def vary_together(a, b):

    for i in range(1,len(a)):

       if (a[i-1] < a[i] and b[i-1] > b[i]) or (a[i-1] > a[i] and b[i-1] < b[i]):

           return False

    return True 

您必须使用大型列表才能看到性能优势。例如,如果:


a = np.array([randint(0,100) for i in range(10000000)])

然后,


vary_together(a, a)  # a as both arguments so as to make it complete the loop

与您的解决方案的性能比较如下:


您的解决方案:8.09s 变化

_together:0.2(在第二次运行时为编译时间打折)。


如果您需要在脚本中一次又一次地运行代码,请cache=True在nb.njit装饰器中执行。


查看完整回答
反对 回复 2021-08-17
?
蓝山帝景

TA贡献1843条经验 获得超7个赞

我们可以使用 python 迭代器提供的惰性求值,这意味着一旦它们没有相同的变化符号,我们就不需要继续遍历两个列表(结构)


def compare_variation( a, b ):

    a_variations = ( a[ i - 1 ] < a[ i ] for i in range( 1, len( a ) ) )

    b_variations = ( b[ i - 1 ] < b[ i ] for i in range( 1, len( b ) ) )

    return all( x == y for x, y in zip( a_variations, b_variations  ) )


查看完整回答
反对 回复 2021-08-17
  • 3 回答
  • 0 关注
  • 151 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信