web-dev-qa-db-fra.com

Python Try Catch Block dans lambda

Est-il possible d'utiliser try block dans une fonction lambda. J'ai besoin de la fonction lambda pour convertir une certaine variable en entier, mais toutes les valeurs ne pourront pas être converties en entiers.

31
scriptdiddy

Nan. Un lambda Python ne peut être qu'une expression unique. Utilisez une fonction nommée.

Il est pratique d’écrire une fonction générique pour convertir les types:

def tryconvert(value, default, *types):
    for t in types:
        try:
            return t(value)
        except (ValueError, TypeError):
            continue
    return default

Ensuite, vous pouvez écrire votre lambda:

lambda v: tryconvert(v, 0, int)

Vous pouvez également écrire tryconvert() pour que renvoie une fonction prenant la valeur à convertir; alors vous n'avez pas besoin du lambda:

def tryconvert(default, *types):
    def convert(value):
        for t in types:
            try:
                return t(value)
            except (ValueError, TypeError):
                continue
        return default
    # set name of conversion function to something more useful
    namext = ("_%s_" % default) + "_".join(t.__for t in types)
    if hasattr(convert, "__qualname__"): convert.__qual+= namext
    convert.__+= namext
    return convert

Maintenant, tryconvert(0, int) renvoie une fonction qui prend une valeur et la convertit en un entier, puis renvoie 0 si cela ne peut être fait.

47
kindall

Dans ce cas spécifique, vous pouvez éviter d'utiliser un bloc try comme ceci:

lambda s: int(s) if s.isdigit() else 0

La méthode de chaîne isdigit() renvoie true si tous les caractères de s sont des chiffres. (Si vous devez accepter des nombres négatifs, vous devrez procéder à une vérification supplémentaire.)

22
Greg Hewgill

En fonction de vos besoins, une autre approche pourrait être de garder l’essai: attraper à l’extérieur de lambda fn

toint  = lambda x : int(x)
strval = ['3', '']

for s in strval:
    try:
        print 2 + toint(s)
    except ValueError:
        print 2

Sortie:

5
2
1
user

Bien qu'il n'y ait pas de moyen général de gérer les exceptions dans une expression lambda, vous pouvez l'obtenir de manière restreinte pour au moins un type d'exception; Jeter un StopIteration d'une partie d'une expression et l'attraper dans une autre partie est réalisable; voir:

from random import randrange

list((lambda:(yield from (randrange(0,2) or next(iter(())) for _ in (None,))))())

next(iter(())) soulève un StopIteration tandis que yield from l'attrape; l'expression ci-dessus renvoie au hasard [] ou [1] en fonction de la valeur aléatoire interne (un 0 lève l'exception et un 1 sera normalement évalué).

Vous pouvez en savoir plus à ce sujet ta http://baruchel.github.io/python/2018/06/20/python-exceptions-in-lambda/ .

0
Thomas Baruchel