13

I have a list of values and I'd like to set the maximum value of any element in the list to 255 and the minimum value to 0 while leaving those within the range unchanged.

oldList = [266, 40, -15, 13]

newList = [255, 40, 0, 13]

Currently I'm doing

for i in range(len(oldList)):
    if oldList[i] > 255:
        oldList[i] = 255
    if oldList[i] < 0:
        oldList[i] = 0

or similarly with newList.append(oldList[i]).

But there has to be a better way than that, right?

user1251007
  • 15,891
  • 14
  • 50
  • 76
jayelm
  • 7,236
  • 5
  • 43
  • 61

3 Answers3

25

Use min, max functions:

>>> min(266, 255)
255
>>> max(-15, 0)
0

>>> oldList = [266, 40, -15, 13]
>>> [max(min(x, 255), 0) for x in oldList]
[255, 40, 0, 13]
falsetru
  • 357,413
  • 63
  • 732
  • 636
8

Another option is is numpy.clip

>>> import numpy as np
>>> np.clip([266, 40, -15, 13], 0, 255)
array([255,  40,   0,  13])
jayelm
  • 7,236
  • 5
  • 43
  • 61
2

You can use map and lambda in Python. Example:

newList= map(lambda y: max(0,min(255,y)), oldList)

You can even nest them if it's a multidimensional list. Example:

can=map(lambda x: map(lambda y: max(0.0,min(10.0,y)), x), can)
can=[[max(min(u,10.0),0.0) for u in yy] for yy in can] 

However I think using the for loop as mentioned above is faster than map lambda for this case. I tried it on a rather large list (2 million float) and got-

time python trial.py

real    0m14.060s
user    0m10.542s
sys     0m0.594s

Using a for and-

time python trial.py

real    0m15.813s
user    0m12.243s
sys     0m0.627s 

Using map lambda.

Another alternative is-

newList=np.clip(oldList,0,255)

It is convenient for any dimensionality and very fast.

time python trial.py

real    0m10.750s
user    0m7.148s
sys     0m0.735s