我有以下代码:

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行。那很冗长,有点丑陋...我敢说,这很 联合国情调.

还有其他更简单,更紧凑的解决方案吗? (和更多 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 有!,使用普通的python。 Numpy版本可能并不奇怪,是最慢的。可能是因为它正在寻找阵列,其他版本只是订购了他们的论点。

链接 max()min() 在一起是我见过的普通成语。如果您觉得很难读取,请编写辅助功能以封装操作:

def clamp(minimum, x, maximum):
    return max(minimum, min(x, maximum))

我心爱的可读python语言发生了什么事? :-)

认真地说,只需使其成为一个功能:

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)

如果愿意,您甚至可以将Min/Max列入列表,因此看起来更“数学上纯”:

x = restrict(val+7, [0, 42])

对我来说,这似乎更具Pythonic:

>>> 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)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top