一般来说,使用FOP(函数式编程)可以将所有内容放在一行中,并在其中嵌套lambda表达式,但这通常是不好的礼仪,因为在嵌套2个函数后,它变得难以阅读。
解决这种问题的最佳方法是将其分成几个阶段:
1:将字符串拆分为元组:
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嵌套
可以产生更简洁的解决方案,而且您实际上可以像下面这样嵌入非离散嵌套类型的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 = map( lambda x: tuple( map( lambda y: int(y) is y.isdigit() else y , x.split('-') ) , a)
但是,正如你所看到的,如果列表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 )\
)))\
)\
)
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)
res = sorted( res, key=lambda x: ( int(x[1]), x[0] ) )
res = map( '-'.join, res )
这就是我要说的全部内容。祝玩得愉快。我已经在py 3.6
中测试了所有的代码。
PS. 一般来说,你有两种方法来使用lambda函数
:
mult = lambda x: x*2
mu_add= lambda x: mult(x)+x #calling lambda from lambda
这种方法对于典型的FOP很有用,其中您拥有常量数据,并且需要操作该数据的每个元素。但是,如果您需要在lambda
中解决list、tuple、string、dict
等容器/包装类型,这些操作就不是非常有用了,因为如果任何这些容器/包装类型存在,则容器内部元素的数据类型变得可疑。因此,我们需要提高抽象级别并确定如何根据其类型操作数据。
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
str_i = lambda x: str(x)
int_str = lambda x: str_i(x)*x
有些人称这种语法为嵌套 lambda,我则称其为 indiscreet,因为你可以看到全部。
而且您可以使用递归 lambda 分配:
def rec_lambda( data, *arg_lambda ):
arg_lambda = [ x for x in arg_lambda if type(x).__name__ == 'function' ]
data = arg_lambda[0](data)
if arg_lambda[1:]:
return rec_lambda( data, *arg_lambda[1:] )
else:
return data
a = rec_lambda( 'a', lambda x: x*2, str.upper, lambda x: (x,x), '-'.join)
>>> 'AA-AA'
key=lambda x:(int((x.split('-') as y)[0]), y[1])
的语法,而我对这种语法并不感兴趣。 - chepnersorted(lst, key= lambda x: x[::-1])
。 - Chris_Rands