J'ai le code suivant:
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]
Fondamentalement, je calcule un nouvel index et l'utilise pour trouver un élément d'une liste. Afin de m'assurer que l'index est dans les limites de la liste, j'avais besoin d'écrire ces 2 if
instructions réparties sur 4 lignes. C'est assez bavard, un peu moche ... Oserais-je dire, c'est assez antipythonique .
Existe-t-il une autre solution plus simple et plus compacte? (et plus pythonique )
Oui, je sais que je peux utiliser if else
en une seule ligne, mais ce n'est pas lisible:
new_index = 0 if new_index < 0 else len(mylist) - 1 if new_index >= len(mylist) else new_index
Je sais aussi que je peux enchaîner max()
et min()
ensemble. C'est plus compact, mais je trouve que c'est un peu obscur, plus difficile de trouver des bugs si je tape mal. En d'autres termes, je ne trouve pas cela très simple.
new_index = max(0, min(new_index, len(mylist)-1))
clamp = lambda value, minv, maxv: max(min(value, maxv), minv)
Utilisation de l'API d' arma.sourceforge.netRéponses:
C'est assez clair, en fait. Beaucoup de gens l'apprennent rapidement. Vous pouvez utiliser un commentaire pour les aider.
la source
def clamp(n, smallest, largest): return max(smallest, min(n, largest))
helperFunctions.py
? Un module séparé? Et si cela était jonché de diverses «fonctions d'aide» pour des choses complètement différentes?utils.py
par exemple:
la source
sorted()
intégrée. Très compact, mais c'est juste un peu obscur. Quoi qu'il en soit, c'est toujours agréable de voir d'autres solutions créatives!min(max())
construction. Très légèrement plus rapide dans le cas où le nombre est dans la plage et aucun échange n'est nécessaire.beaucoup de réponses intéressantes ici, toutes à peu près identiques, sauf ... laquelle est la plus rapide?
paxdiablo l' a!, utilise du python ordinaire. La version numpy est, peut-être sans surprise, la plus lente du lot. Probablement parce qu'il recherche des tableaux, où les autres versions ne font que commander leurs arguments.
la source
mm_clip
et cepy_clip
sera tout aussi rapide si vous utilisez le compilateur JIT, comme PyPy. Sauf que le premier est plus lisible et que la lisibilité est plus importante dans la philosophie de Python qu'un léger gain de performances la plupart du temps.Voir numpy.clip :
la source
clip
esta
, un «tableau contenant des éléments à découper». Vous auriez donc à écrirenumpy.clip([index], …
, nonnumpy.clip(index, …
.L'enchaînement
max()
etmin()
ensemble est l'idiome normal que j'ai vu. Si vous avez du mal à lire, écrivez une fonction d'assistance pour encapsuler l'opération:la source
Qu'est-il arrivé à mon langage Python lisible bien-aimé? :-)
Sérieusement, faites-en une fonction:
alors appelez-le simplement avec quelque chose comme:
Ou une solution plus simple et plus flexible où vous faites vous-même le calcul:
Si vous le souhaitez, vous pouvez même créer une liste min / max pour qu'elle paraisse plus "mathématiquement pure":
la source
min
etmax
sont beaucoup plus clairs qu'un tas de conditions. (Je ne sais pas à quoi çaadd
sert - dis justeclamp(val + 7, 0, 42)
.)Celui-ci me semble plus pythonique:
Quelques tests:
la source
Si votre code semble trop lourd, une fonction peut vous aider:
la source
Évitez d'écrire des fonctions pour des tâches aussi petites, sauf si vous les appliquez souvent, car cela encombrera votre code.
pour les valeurs individuelles:
pour les listes de valeurs:
la source