vacia una palabra metodos listas lista len funcion for español elementos crear buscar arreglos agregar python clamp

una - funcion len python



Cómo fijar un entero a un rango?(en Python) (9)

Tengo el siguiente código:

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]

Básicamente, calculo un nuevo índice y lo uso para encontrar algún elemento de una lista. Para asegurarme de que el índice esté dentro de los límites de la lista, necesitaba escribir esos 2 if declaraciones se distribuyen en 4 líneas. Eso es bastante detallado, un poco feo ... Atrévete, es bastante antipático .

¿Hay alguna otra solución más simple y más compacta? (y más pitónico )

Sí, sé que puedo usar if else en una línea, pero no es legible:

new_index = 0 if new_index < 0 else len(mylist) - 1 if new_index >= len(mylist) else new_index

También sé que puedo encadenar max() y min() juntos. Es más compacto, pero creo que es un poco oscuro, más difícil de encontrar errores si lo escribo mal. En otras palabras, no me parece muy sencillo.

new_index = max(0, min(new_index, len(mylist)-1))


¿Qué pasó con mi amado lenguaje Python legible? :-)

En serio, solo hazlo una función:

def addInRange (val, add, minval, maxval): newval = val + add if newval < minval: return minval if newval > maxval: return maxval return newval

entonces solo llámalo con algo como:

val = addInRange (val, 7, 0, 42)

O una solución más simple, más flexible, donde usted mismo realiza el cálculo:

def restrict (val, minval, maxval): if val < minval: return minval if val > maxval: return maxval return val x = restrict (x+10, 0, 42)

Si quisieras, incluso podrías hacer una lista min / max para que parezca más "matemáticamente pura":

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


Aquí hay muchas respuestas interesantes, todas iguales, excepto ... ¿cuál es más rápido?

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 tiene !, usa plain ol ''python. La versión numpy es, quizás no sorprendentemente, la más lenta de todas. Probablemente porque está buscando matrices, donde las otras versiones simplemente ordenan sus argumentos.


Encadenar max() y min() juntos es la expresión normal que he visto. Si le resulta difícil de leer, escriba una función auxiliar para encapsular la operación:

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


Este me parece más pitónico:

>>> def clip(val, min_, max_): ... return min_ if val < min_ else max_ if val > max_ else val

Algunas pruebas:

>>> clip(5, 2, 7) 5 >>> clip(1, 2, 7) 2 >>> clip(8, 2, 7) 7


Esto es bastante claro, en realidad. Mucha gente lo aprende rápidamente. Puedes usar un comentario para ayudarlos.

new_index = max(0, min(new_index, len(mylist)-1))


Evite escribir funciones para tareas tan pequeñas, a menos que las aplique con frecuencia, ya que esto desordenará su código.

para valores individuales:

min(clamp_max, max(clamp_min, value))

para listas de valores:

map(lambda x: min(clamp_max, max(clamp_min, x)), values)


Si su código parece demasiado difícil de manejar, una función podría ayudar:

def clamp(minvalue, value, maxvalue): return max(minvalue, min(value, maxvalue)) new_index = clamp(0, new_index, len(mylist)-1)


Ver numpy.clip :

index = numpy.clip(index, 0, len(my_list) - 1)


sorted((minval, value, maxval))[1]

por ejemplo:

>>> 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