How to change numbers in a list to make it monotonically decreasing?

Question:

I have got a list:

first = [100, 110, 60]

How to make that: if the next number is greater than the previous one, then it is necessary to reduce this number like preceding number.
For example, the answer should be:

ans = [100, 100, 60]

The second example:

arr = [60,50,60]
ans = [60, 50, 50]

The third example:

arr = [20, 100, 150]
ans = [20, 20, 20]

I try to, but i think it’s not good idea

for i in range(len(arr)-1):

    if arr[i] < arr[i+1]:
        answer.append(a[i+1] - 10)
    if arr[i] < arr[i+1]:
        answer.append(a[i])
    if arr[i] < arr [i+1]:
        answer.append(arr[-1])
Asked By: Proger228

||

Answers:

I think it should work as following:

list = [20, 100, 100]

out = list[0]

for x in range(len(list)-1):
   if list[x+1] > list[x]:
      out.append(list[x])
   else:
      out.append(list[x+1])

print(out)
Answered By: kaliiiiiiiii

Not a one liner, but maybe something like

last = max(arr)
ans = []
for item in arr:
   last = min(last, item)
   ans.append(last)
Answered By: saquintes

This will modify the list in situ:

def fix_list(_list):
    for i, v in enumerate(_list[1:], 1):
        _list[i] = min(v, _list[i-1])
    return _list


print(fix_list([100, 110, 60]))
print(fix_list([60, 50, 60]))
print(fix_list([20, 100, 150]))

Output:

[100, 100, 60]
[60, 50, 50]
[20, 20, 20]
Answered By: Pingu

This is a special case of a scan/prefix sum operation, available in Python as itertools.accumulate:

ans = list(itertools.accumulate(arr, min))

Basically, this will output a list that, at each position, contains the minimum element of the input list up to that point.

Answered By: Konrad Rudolph
arr1 = [50, 70, 10, 120, 150]
arr2 = []
for i, x in enumerate(arr1):
    if x <= arr1[i-1] or i==0:
        arr2.append(x)
    else:
        if x <= arr2[i-1]:
            arr2.append(arr1[i-1])
        else:
            arr2.append(arr2[i-1])
print(arr2)

Hope this helps.

Answered By: marick

Here is another alternative using list comprehension, for those that are interested.

ans = [min(arr[:i]) if i > 0 and a > min(arr[:i]) else a for i, a in enumerate(arr)]

Here is an example:

Code:

arr = [100, 110, 105, 90, 110]
ans = [min(arr[:i]) if i > 0 and a > min(arr[:i]) else a for i, a in enumerate(arr)]
print(ans)

Output:

[100, 100, 100, 90, 90]
Answered By: ScottC
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.