정수를 특정 범위로 고정하는 방법은 무엇입니까?
다음 코드가 있습니다.
new_index = index + offset
if new_index < 0:
new_index = 0
if new_index >= len(mylist):
new_index = len(mylist) - 1
return mylist[new_index]
기본적으로 새 인덱스를 계산하고이를 사용하여 목록에서 일부 요소를 찾습니다. 인덱스가 목록의 경계 내에 있는지 확인하기 위해 두 개의 if
문을 4 줄로 나누어 작성해야했습니다 . 그것은 아주 장황하고, 약간 못 생겼습니다 ... 감히 말하지만, 그것은 아주 비단뱀 적 입니다.
더 간단하고 컴팩트 한 다른 솔루션이 있습니까? (그리고 더 pythonic )
예, if else
한 줄로 사용할 수 있지만 읽을 수 없습니다.
new_index = 0 if new_index < 0 else len(mylist) - 1 if new_index >= len(mylist) else new_index
나는 또한 체인을 할 수있는 알 max()
과 min()
함께. 더 콤팩트하지만 잘못 입력하면 버그를 찾기가 더 어렵고 모호하다고 느낍니다. 즉, 매우 간단하지 않습니다.
new_index = max(0, min(new_index, len(mylist)-1))
이것은 실제로 꽤 명확합니다. 많은 사람들이 그것을 빨리 배웁니다. 댓글을 사용하여 도움을 줄 수 있습니다.
new_index = max(0, min(new_index, len(mylist)-1))
sorted((minval, value, maxval))[1]
예를 들면 :
>>> minval=3
>>> maxval=7
>>> for value in range(10):
... print sorted((minval, value, maxval))[1]
...
3
3
3
3
4
5
6
7
7
7
numpy.clip 참조 :
index = numpy.clip(index, 0, len(my_list) - 1)
여기에 많은 흥미로운 답변이 있습니다. 모두 비슷하지만 ... 어느 것이 더 빠릅니까?
import numpy
np_clip = numpy.clip
mm_clip = lambda x, l, u: max(l, min(u, x))
s_clip = lambda x, l, u: sorted((x, l, u))[1]
py_clip = lambda x, l, u: l if x < l else u if x > u else x
>>> import random
>>> rrange = random.randrange
>>> %timeit mm_clip(rrange(100), 10, 90)
1000000 loops, best of 3: 1.02 µs per loop
>>> %timeit s_clip(rrange(100), 10, 90)
1000000 loops, best of 3: 1.21 µs per loop
>>> %timeit np_clip(rrange(100), 10, 90)
100000 loops, best of 3: 6.12 µs per loop
>>> %timeit py_clip(rrange(100), 10, 90)
1000000 loops, best of 3: 783 ns per loop
paxdiablo 가 있습니다!, 일반 ol 'python을 사용하십시오. numpy 버전은 당연히 가장 느린 버전입니다. 아마도 다른 버전이 인수를 정렬하는 배열을 찾고 있기 때문일 것입니다.
Chaining max()
and min()
together는 내가 본 정상적인 관용구입니다. 읽기 어려운 경우 작업을 캡슐화하는 도우미 함수를 작성하십시오.
def clamp(minimum, x, maximum):
return max(minimum, min(x, maximum))
내가 사랑하는 읽을 수있는 파이썬 언어는 어떻게 되었습니까? :-)
진지하게, 그냥 함수로 만드세요 :
def addInRange(val, add, minval, maxval):
newval = val + add
if newval < minval: return minval
if newval > maxval: return maxval
return newval
그런 다음 다음과 같이 호출하십시오.
val = addInRange(val, 7, 0, 42)
Or a simpler, more flexible, solution where you do the calculation yourself:
def restrict(val, minval, maxval):
if val < minval: return minval
if val > maxval: return maxval
return val
x = restrict(x+10, 0, 42)
If you wanted to, you could even make the min/max a list so it looks more "mathematically pure":
x = restrict(val+7, [0, 42])
This one seems more pythonic to me:
>>> def clip(val, min_, max_):
... return min_ if val < min_ else max_ if val > max_ else val
A few tests:
>>> clip(5, 2, 7)
5
>>> clip(1, 2, 7)
2
>>> clip(8, 2, 7)
7
If your code seems too unwieldy, a function might help:
def clamp(minvalue, value, maxvalue):
return max(minvalue, min(value, maxvalue))
new_index = clamp(0, new_index, len(mylist)-1)
Avoid writing functions for such small tasks, unless you apply them often, as it will clutter up your code.
for individual values:
min(clamp_max, max(clamp_min, value))
for lists of values:
map(lambda x: min(clamp_max, max(clamp_min, x)), values)
참고URL : https://stackoverflow.com/questions/4092528/how-to-clamp-an-integer-to-some-range
'code' 카테고리의 다른 글
Android-브로드 캐스트 수신기 onReceive ()에서 컨텍스트 가져 오기 (0) | 2020.10.06 |
---|---|
Entity Framework-코드 우선-목록을 저장할 수 없음 (0) | 2020.10.06 |
500.21 모듈 목록에 잘못된 모듈“ManagedPipelineHandler”가 있습니다. (0) | 2020.10.06 |
NSArray를 NSData로 변환하는 방법? (0) | 2020.10.06 |
presentModalViewController를 사용하여 투명한보기를 만드는 방법 (0) | 2020.10.06 |