通常使用 FOP(面向函数的编程),您可以将所有内容放在一个内衬中,并将 lambdas 嵌套在一个内衬中,但这通常是不好的礼仪,因为在 2 个嵌套函数之后,所有内容都变为很不可读。
解决此类问题的最佳方法是将其分成几个阶段:
1:将字符串拆分成tuple:
lst = ['b-3', 'a-2', 'c-4', 'd-2']
res = map( lambda str_x: tuple( str_x.split('-') ) , lst)
2:按照您的意愿对元素进行排序:
lst = ['b-3', 'a-2', 'c-4', 'd-2']
res = map( lambda str_x: tuple( str_x.split('-') ) , lst)
res = sorted( res, key=lambda x: ( int(x[1]), x[0] ) )
由于我们将字符串拆分为元组,它将返回一个映射对象,该对象将表示为元组列表。所以现在第三步是可选的:
3:代表您查询的数据:
lst = ['b-3', 'a-2', 'c-4', 'd-2']
res = map( lambda str_x: tuple( str_x.split('-') ) , lst)
res = sorted( res, key=lambda x: ( int(x[1]), x[0] ) )
res = map( '-'.join, res )
现在请记住,lambda nesting 可以产生更单行的解决方案,并且您实际上可以嵌入非离散嵌套类型的 lambda,如下所示:
a = ['b-3', 'a-2', 'c-4', 'd-2']
resa = map( lambda x: x.split('-'), a)
resa = map( lambda x: ( int(x[1]),x[0]) , a)
# resa can be written as this, but you must be sure about type you are passing to lambda
resa = map( lambda x: tuple( map( lambda y: int(y) is y.isdigit() else y , x.split('-') ) , a)
但是您可以看到 list a 的内容是否除了由 '-' 分隔的 2 个字符串类型之外,lambda 函数会引发错误,您将很难弄清楚是什么地狱正在发生。
所以最后,我想向你展示第三步程序的几种编写方式:
1:
lst = ['b-3', 'a-2', 'c-4', 'd-2']
res = map( '-'.join,\
sorted(\
map( lambda str_x: tuple( str_x.split('-') ) , lst),\
key=lambda x: ( int(x[1]), x[0] )\
)\
)
2:
lst = ['b-3', 'a-2', 'c-4', 'd-2']
res = map( '-'.join,\
sorted( map( lambda str_x: tuple( str_x.split('-') ) , lst),\
key=lambda x: tuple( reversed( tuple(\
map( lambda y: int(y) if y.isdigit() else y ,x )\
)))\
)\
) # map isn't reversible
3:
res = sorted( lst,\
key=lambda x:\
tuple(reversed(\
tuple( \
map( lambda y: int(y) if y.isdigit() else y , x.split('-') )\
)\
))\
)
所以你可以看到这一切是如何变得非常复杂和难以理解的。在阅读我自己或其他人的代码时,我经常喜欢看到这个版本:
res = map( lambda str_x: tuple( str_x.split('-') ) , lst) # splitting string
res = sorted( res, key=lambda x: ( int(x[1]), x[0] ) ) # sorting for each element of splitted string
res = map( '-'.join, res ) # rejoining string
这都是我的。玩得开心。我已经测试了py 3.6 中的所有代码。
PS。一般来说,你有两种方法可以接近lambda functions:
mult = lambda x: x*2
mu_add= lambda x: mult(x)+x #calling lambda from lambda
这种方式对于典型的 FOP 很有用,在这种情况下,您有常量数据,并且您需要操作该数据的每个元素。但是,如果您需要在 lambda 中解析 list,tuple,string,dict,这些操作并不是很有用,因为如果存在这些 container/wrapper 类型中的任何一个,那么容器内元素的数据类型就会变得可疑.因此,我们需要提升一个抽象层,并确定如何根据数据类型来操作数据。
mult_i = lambda x: x*2 if isinstance(x,int) else 2 # some ternary operator to make our life easier by putting if statement in lambda
现在你可以使用另一种类型的lambda函数:
int_str = lambda x: ( lambda y: str(y) )(x)*x # a bit of complex, right?
# let me break it down.
#all this could be written as:
str_i = lambda x: str(x)
int_str = lambda x: str_i(x)*x
## we can separate another function inside function with ()
##because they can exclude interpreter to look at it first, then do the multiplication
# ( lambda x: str(x)) with this we've separated it as new definition of function
# ( lambda x: str(x) )(i) we called it and passed it i as argument.
有些人将这种类型的语法称为嵌套 lambda,我称其为轻率,因为您可以看到所有内容。
你可以使用递归 lambda 赋值:
def rec_lambda( data, *arg_lambda ):
# filtering all parts of lambda functions parsed as arguments
arg_lambda = [ x for x in arg_lambda if type(x).__name__ == 'function' ]
# implementing first function in line
data = arg_lambda[0](data)
if arg_lambda[1:]: # if there are still elements in arg_lambda
return rec_lambda( data, *arg_lambda[1:] ) #call rec_lambda
else: # if arg_lambda is empty or []
return data # returns data
#where you can use it like this
a = rec_lambda( 'a', lambda x: x*2, str.upper, lambda x: (x,x), '-'.join)
>>> 'AA-AA'