我有以下代码:
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 。
还有其他更简单,更紧凑的解决方案吗?(以及更多 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))
答案 0 :(得分:99)
实际上,这很清楚。很多人很快就学会了。您可以使用评论来帮助他们。
new_index = max(0, min(new_index, len(mylist)-1))
答案 1 :(得分:70)
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
答案 2 :(得分:35)
请参阅numpy.clip:
index = numpy.clip(index, 0, len(my_list) - 1)
答案 3 :(得分:33)
这里有很多有趣的答案,差不多都是一样的,除了......哪一个更快?
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&#39;蟒蛇。 numpy版本也许并不奇怪,是最慢的版本。可能是因为它正在寻找数组,其他版本只是在命令它们的参数。
答案 4 :(得分:13)
我心爱的可读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])
答案 5 :(得分:13)
将max()
和min()
链接在一起是我见过的正常习惯用语。如果您发现难以阅读,请编写一个辅助函数来封装操作:
def clamp(minimum, x, maximum):
return max(minimum, min(x, maximum))
答案 6 :(得分:5)
如果你的代码看起来太笨重,那么函数可能会有所帮助:
def clamp(minvalue, value, maxvalue):
return max(minvalue, min(value, maxvalue))
new_index = clamp(0, new_index, len(mylist)-1)
答案 7 :(得分:4)
这个对我来说似乎更加炽热:
>>> 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
答案 8 :(得分:1)
避免为这些小任务编写函数,除非你经常应用它们,因为它会使你的代码混乱。
个人价值:
min(clamp_max, max(clamp_min, value))
表示值列表:
map(lambda x: min(clamp_max, max(clamp_min, x)), values)