숫자를 특정 범위로 클램프(클립, 제한)하려면 어떻게 해야 합니까?
다음 코드가 있습니다.
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]
기본적으로 새 인덱스를 계산하고 목록에서 요소를 찾는 데 사용합니다.인덱스가 목록의 범위 내에 있는지 확인하기 위해, 저는 그 2개를 작성해야 했습니다.if
4줄로 분산된 진술.꽤 장황하고, 좀 못생겼네요...제가 감히 말하건대, 그것은 꽤 비피토닉적입니다.
더 간단하고 더 콤팩트한 해결책이 있습니까?(그리고 더 파이썬틱)
네, 제가 사용할 수 있다는 것을 압니다.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))
목록 값을 상한 및 하한(클램핑, 클리핑, 임계값)으로 대체하는 Pythonic 방법을 참조하십시오.Numpy 배열에서 값을 처리하는 특정 매개 변수입니다.
사실 이것은 꽤 명확합니다.많은 사람들이 그것을 빨리 배웁니다.여러분은 댓글을 사용하여 그들을 도울 수 있습니다.
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
여기에 있는 많은 흥미로운 대답들은 모두 거의 비슷하지만, ...을 제외하고는.어느 것이 더 빠릅니까?
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
팍스 디아블로가 가지고 있어요!, 플레인 올 파이썬을 사용하세요.아마 놀랄 것도 없이, numpy 버전은 가장 느립니다.아마도 다른 버전들이 그들의 주장을 나열하는 배열을 찾고 있기 때문일 것입니다.
numpy.clip 참조:
index = numpy.clip(index, 0, len(my_list) - 1)
내가 사랑하는 읽을 수 있는 파이썬 언어는 어떻게 되었습니까? :-)
진지하게, 그냥 기능으로 만들어 보세요.
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)
또는 직접 계산을 수행할 수 있는 보다 간단하고 유연한 솔루션:
def restrict(val, minval, maxval):
if val < minval: return minval
if val > maxval: return maxval
return val
x = restrict(x+10, 0, 42)
원하는 경우 최소/최대를 목록으로 만들어 "수학적으로 순수한" 것처럼 보이게 할 수도 있습니다.
x = restrict(val+7, [0, 42])
체인링max()
그리고.min()
함께 하는 것이 제가 본 일반적인 관용구입니다.읽기가 어려울 경우 작업을 캡슐화하는 도우미 기능을 작성합니다.
def clamp(minimum, x, maximum):
return max(minimum, min(x, maximum))
이건 제가 보기에 더 심술궂어 보입니다.
>>> def clip(val, min_, max_):
... return min_ if val < min_ else max_ if val > max_ else val
몇 가지 테스트:
>>> clip(5, 2, 7)
5
>>> clip(1, 2, 7)
2
>>> clip(8, 2, 7)
7
코드가 너무 다루기 어려운 경우 다음과 같은 기능이 도움이 될 수 있습니다.
def clamp(minvalue, value, maxvalue):
return max(minvalue, min(value, maxvalue))
new_index = clamp(0, new_index, len(mylist)-1)
자주 적용하지 않는 한 이러한 작은 작업에 대한 함수를 작성하지 마십시오. 코드가 복잡해질 수 있습니다.
개별 값의 경우:
min(clamp_max, max(clamp_min, value))
값 목록의 경우:
map(lambda x: min(clamp_max, max(clamp_min, x)), values)
언급URL : https://stackoverflow.com/questions/4092528/how-can-i-clamp-clip-restrict-a-number-to-some-range
'source' 카테고리의 다른 글
SQL Server 케이스 문(IS NULL인 경우) (0) | 2023.07.19 |
---|---|
다시 삽입하지 않고 PyMongo의 MongoDB 문서 배열에 항목 추가 (0) | 2023.07.19 |
SQL/Oracle: 여러 열의 인덱스를 사용할 수 있는 경우 (0) | 2023.07.19 |
setup.py 설치의 종속성을 확인하는 데 esx_install이 아닌 esxcli를 사용할 수 있습니까? (0) | 2023.07.19 |
패키지 데이터를 설정 도구/디스트리뷰트와 함께 포함하는 방법은 무엇입니까? (0) | 2023.07.19 |