迭代一个列表,然后减去1,然后在python中弹出

迭代一个列表,然后减去1,然后在python中弹出,python,Python,我想迭代一个列表,首先弹出最后一个元素,然后从所有值中减去1,然后重复。我想将弹出的元素保存在一个新列表中 输入-[5957] 输出-[7 4 7 2] 解释- 首先我们弹出7,然后列表保持为5,9,5,然后我们从剩下的3个数字中减去1,然后弹出4,因为(5-1)同样向前。当数字为0时,我们不向前减法,数组的元素不应该为负数 我试着对它进行编码,但无法理解其中的逻辑- n = int(input()) arr = sorted(list(int(num) for num in input().s

我想迭代一个列表,首先弹出最后一个元素,然后从所有值中减去1,然后重复。我想将弹出的元素保存在一个新列表中

输入-[5957]

输出-[7 4 7 2]

解释-

首先我们弹出7,然后列表保持为5,9,5,然后我们从剩下的3个数字中减去1,然后弹出4,因为(5-1)同样向前。当数字为0时,我们不向前减法,数组的元素不应该为负数

我试着对它进行编码,但无法理解其中的逻辑-

n = int(input())
arr = sorted(list(int(num) for num in input().strip().split()))[:n]
result = []
for j in range(1,n):
     a=arr.pop()
     for i in range(1,n):
        if(arr[i] > i):
           arr[i] = arr[i] - 1
        else:
           arr[i] = 0
你可以

  • 使用反向迭代器创建反向列表
  • 然后在上面列举你所处的索引
  • 然后将元素值附加到索引减去的元素值,以完成所需的操作
代码:

解决方案

l=[5,9,5,7]
result= []

for i in range(0,len(l)): 
    last_elem = l.pop() 
    result.append(last_elem) 
    l = [i-1 for i in l]
print(result)

这可以在一个更具python风格的单行程序中完成:

out_arr = [in_arr[i] + (i+1) for i in range(-1, -1*len(in_arr)-1, -1)] # [7, 4, 7, 2]

这取决于您减少元素的观察结果(由@Thierry Lathuille指出)。在我的回答中,我使用更快的列表理解来生成输出列表。这解释了for循环的作用:
对于范围内的i(开始索引=-1,开始索引=-5,步长大小=-1)
如果您想构建一个新列表,一个好方法是使用列表理解

如果要在列表上迭代并使用项的索引,请使用将在每次迭代中提供项和项的索引的。它比在索引上迭代更好、更干净

要以相反顺序迭代列表,请使用

因此,结合所有这些,一个好的、简短的、类似Python的解决方案可以是:

data = [5, 9, 5, 7]

out = [item - index for index, item in enumerate(reversed(data))]

print(out)
# [7, 4, 7, 2]

我做了一些计时来测试这个解决方案与使用索引(并添加了第三个解决方案,使用切片与
[::1]

输出:

204 ms ± 3.73 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
141 ms ± 322 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
156 ms ± 398 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

使用
反向
枚举
总是比使用索引快30%左右(即使对于10个项目的小列表也是如此)。切片比使用
reversed
要慢一点-我想这是由于创建了反向列表,而
reversed
只是在原始文件上迭代。

你真的必须这样做吗?你可以只取最后一项,然后是前一项减去1,前一项减去2等等,这样效率也会更高。@Thierrylahuille我认为这是因为我是编程新手。我无法编写相同的代码。你能给我一个片段吗。我的意思是:这是一些家庭作业,你被要求按照你描述的方式来完成它(弹出,将一减去所有剩余的项目,重复),还是你只想要预期的输出,不管你使用什么方法,在这种情况下,有更简单、更有效的方法来完成它。@Thierrylahuille不,这不是家庭作业,我只是想高效地编写代码,我尝试了pop方法,迭代和pop时的错误是“列表索引超出范围”,我知道我不能同时进行pop和迭代,而且我想迭代到arr[I]>I,这样数字就不会出现负数。你能帮忙吗?如何检查“此处减法”中的条件?当我传递一个已排序的列表时,我希望将其写入一个[i]>iThe“for”循环,以确保在所有元素上迭代一次。如果使用反向迭代器,它将有效地停止在0处(即在C语言中检查i>=0)。减法如@Thierry lathuille所述。相反:索引0:7-0=7索引1:5-1=4索引2:9-2=7索引3:5-3=2我不想,我想数组的新元素变成负数,当数组的元素变成0时,我想停在0。请阅读我的全部问题。@Aryanzha她只是从旧元素中减去1,而不是从新元素中减去1。我想你还不明白解决办法。
data = [100] * 1000000


def with_indices(in_arr):
    return [in_arr[i] + (i+1) for i in range(-1, -1*len(in_arr)-1, -1)]

def with_reversed(data):
    return [item - index for index, item in enumerate(reversed(data))]

def with_slice(data):
    return [item - index for index, item in enumerate(data[::-1])]

%timeit with_indices(data)
%timeit with_reversed(data)
%timeit with_slice(data)
204 ms ± 3.73 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
141 ms ± 322 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
156 ms ± 398 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)