当第一个元素大于下一个元素时,减去列表中的连续元素-Python

时间:2018-07-31 20:18:13

标签: python list performance loops subtraction

我正在编写一个程序,可以完成以下任务:

输入列表a时,如果结果为非负数,它将减去连续的元素(从头开始)。 例如,如果

a=[3,2,1]

然后将减去连续的数字,因此先a=[1,1],然后再a=[0]。同样,结果中所有数字都必须升序(例如2,1不能在列表中)。另一个例子:

a=[1, 10, 7, 3, 2]
[1, 3, 3, 2] #10-7 (10 and 7 get replaced with 3)
[1, 0, 2]    #3-3  (precedence goes to the left: 3-3 gets subtracted, not 3-2)
[1, 2]       #1-0

这是我当前的代码(其中a是随机生成的):

import random
a=[random.randint(1,10) for e in range(20)]
print(a)
loop=1
while True:
    try:
        #print(loop,a)
        subloop=0
        while subloop<loop:
            if a[loop-subloop]<=a[loop-1-subloop]:
                a[loop-1-subloop]=a[loop-1-subloop]-a.pop(loop-subloop)
                if loop!=1:
                    loop-=1
            subloop+=1
        if a[loop]<=a[loop-1]:
            a[loop-1]=a[loop-1]-a.pop(loop)
        else:
            loop+=1
    except IndexError:
        break
print(a)

这段代码有点长/效率低下。有没有更好或更短/更有效的方法来做到这一点?

2 个答案:

答案 0 :(得分:3)

这是我的看法:

a = [1, 10, 7, 3, 2]
b = [3, 2, 1]


def index_helper(l):
    for i, x in enumerate(l[:-1]):
        if l[i] >= l[i+1]:
            return i


def reduce(l):
    i = index_helper(l)
    while i is not None:
        l[i:i + 2] = [l[i] - l[i + 1]]
        i = index_helper(l)
    return l


>>> reduce(a)
[1, 2]

>>> reduce(b)
[0]

答案 1 :(得分:1)

另一种替代解决方案:

  def my_func(a):
    next_i = next((如果(a [i]-a [i + 1])> = 0),则无((i代表范围(len(a)-1)中的i,i)= 0),无)
    而next_i不是None时:
        a = a [:next_i] + [a [next_i]-a [next_i + 1]] + a [next_i + 2:]
        next_i = next((如果(a [i]-a [i + 1])> = 0),则无((i代表范围(len(a)-1)中的i,i)= 0),无)
    返回一个

打印(my_func(a = [1,10,7,3,2]))
#[1,2]

print(my_func(a = [3,2,1]))
#[0]
 

但是,这比@bphi的解决方案慢一点:

 导入随机
N = 10000
a_list = [对于范围(N)中的_ [[random.randint(1,10)for e在范围(20)]]

all([reduce(l)== my_func(l)for a_list中的l])#验证答案是否相同
#真正

%% timeit
[a_list中l的my_func(l)]
每个循环#10.7 ms±358 µs(平均±标准偏差,共运行7次,每个循环100个)

%% timeit
[为a_list中的l减少(l)]
每个循环#7.51 ms±416 µs(平均±标准偏差,共运行7次,每个循环100个)