问题
Is it possible to use try catch block inside of a lambda function. I need the lambda function to convert a certain variable into an integer, but not all of the values will be able to be converted into integers.
回答1:
Nope. A Python lambda can only be a single expression. Use a named function.
It is convenient to write a generic function for converting types:
def tryconvert(value, default, *types):
for t in types:
try:
return t(value)
except (ValueError, TypeError):
continue
return default
Then you can write your lambda:
lambda v: tryconvert(v, 0, int)
You could also write tryconvert()
so it returns a function that takes the value to be converted; then you don't need the 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.__name__ for t in types)
if hasattr(convert, "__qualname__"): convert.__qualname__ += namext
convert.__name__ += namext
return convert
Now tryconvert(0, int)
returns a function that takes a value and converts it to an integer, and returns 0
if this can't be done.
回答2:
In this specific instance, you can avoid using a try
block like this:
lambda s: int(s) if s.isdigit() else 0
The isdigit() string method returns true if all the characters of s
are digits. (If you need to accept negative numbers, you will have to do some extra checking.)
回答3:
Depending on your need, another approach could be to keep the try:catch outside lambda fn
toint = lambda x : int(x)
strval = ['3', '']
for s in strval:
try:
print 2 + toint(s)
except ValueError:
print 2
Output:
5
2
回答4:
While there is no general way for handling exceptions in a lambda expression, you can achieve it in a restricted way for at least one kind of exception; throwing a StopIteration
from a part of an expression and catching it in another part is achievable; see:
from random import randrange
list((lambda:(yield from (randrange(0,2) or next(iter(())) for _ in (None,))))())
where next(iter(()))
raises a StopIteration
while yield from
will catch it; the expression above randomly returns []
or [1]
according to the inner random value (a 0
will raise the exception and a 1
will be normally evaluated).
You can read more about it ta http://baruchel.github.io/python/2018/06/20/python-exceptions-in-lambda/ .
来源:https://stackoverflow.com/questions/12451531/python-try-catch-block-inside-lambda