Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:有没有优化的方法来检查两个列表是否同时增加?_Python_Sequence - Fatal编程技术网

Python:有没有优化的方法来检查两个列表是否同时增加?

Python:有没有优化的方法来检查两个列表是否同时增加?,python,sequence,Python,Sequence,假设我们有两个列表a=[1,2,4,3,5]和b=[1031228005001000] 是否有一种优化的方法可以检查它们是否“一起增加” 我当前的解决方案采用了一个循环: 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') 对于范围(1,len(a))中的i: 如果(a[i

假设我们有两个列表
a=[1,2,4,3,5]
b=[1031228005001000]

是否有一种优化的方法可以检查它们是否“一起增加”

我当前的解决方案采用了一个循环:

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')
对于范围(1,len(a))中的i:
如果(a[i-1]b[i])或(a[i-1]>a[i]和b[i-1]
有更好的办法吗

注:

  • 解决方案不需要特定于列表(实际上任何数据结构都可以工作)
  • 这两个iterables不需要增加相同数量的单位,只需要一起增加
就O(顺序符号)而言,假设列表没有一定的顺序,那么就没有比线性更好的了。但是,您可以使用诸如cython、numba之类的python编译器来加速代码。您的代码使用:

那么

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

您的解决方案:8.09s
vary_合在一起:0.2(在第二次运行时对编译时间进行折扣)


如果您需要在脚本中反复运行代码,请在
nb.njit
decorator中执行
cache=True

您的速度不可能超过O(n),但是,通过使用
numpy.diff
并比较
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

此解决方案的缺点是它不使用延迟求值,即它计算并比较整个
符号(diff(…)
数组,即使
a
b
的“增量”在第一个位置不同。如果列表很长,则应该考虑使用另一种方法。

< P>可以使用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  ) )
def比较变量(a,b):
a_变量=(a[i-1]
下面是一种理解列表的方法:

c = [(a[x + 1] - a[x]) * (b[x + 1] - b[x]) for x in range(len(a) - 1)]
if any([x < 0 for x in c]):
    print('Wrong')
c=[(a[x+1]-a[x])*(b[x+1]-b[x])表示范围内的x(len(a)-1)]
如果有([x<0表示c中的x]):
打印('错误')

比较所有以前的方法(除了numba方法),tobias_k的答案在处理足够大的列表(大约列出40个元素)时看起来最有效。

通过优化,您希望比当前的O(N)更快?您认为“一起增加”是什么意思?两个列表中的元素是否按递增顺序排序?或者对于所有可能的索引,一个列表中的元素[i]比另一个列表中的元素[i]大?还有什么?好吧,有循环,还有比较运算本身。所以两者都是。看看我是否忘记了CS方法,它更优雅地处理了这个问题。通过使用numpy ndarrays来表达这个问题,您可能会在性能上得到一些改进。@quant我的意思是,无论项目的初始类型如何,如果元素a[I]大于a[I-1]对于列表b中具有相同索引的项目也是如此。如果您仍然计算整个列表
a
b
diff
符号
,那么懒散地评估它们是否相等并不会显著减少操作次数,即使它们在第一次比较中有所不同。@tobias_k valid point我已经相应地更新了我的代码,谢谢。如果a[i-1]
,您可以只编写
a[i-1],而不是
True。另外,我建议切换到Python 3,即只使用
range
zip
,它们现在返回迭代器而不是列表。@tobias_k我已经根据您的建议更改了代码,谢谢loot@tobias_k完全忘记了xrange,非常感谢,非常感谢回答得好。但是对于初学者来说,numba看起来很有异国情调。将vary_与ma=-a相加(a,ma)以强制执行惰性方面。比较有无numba(4例),我发现这是最优雅的,它避免了显式循环。谢谢当你比较两个同时增加的大列表时,你的方法实际上是最快的。
>>> 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
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  ) )
c = [(a[x + 1] - a[x]) * (b[x + 1] - b[x]) for x in range(len(a) - 1)]
if any([x < 0 for x in c]):
    print('Wrong')