Python2列表理解和评估
如何在列表理解或评估中使用多行语句 我试图转换此代码:Python2列表理解和评估,python,lambda,eval,list-comprehension,Python,Lambda,Eval,List Comprehension,如何在列表理解或评估中使用多行语句 我试图转换此代码: def f(x, y, b=''): for i in x: if i in y: y.remove(i) i *= 2 b += i return b 转化为lambda函数,如下所示: j=lambda x,y:''.join(eval('y.remove(i);i*2')if i in y else i for i in x) 在这两个
def f(x, y, b=''):
for i in x:
if i in y:
y.remove(i)
i *= 2
b += i
return b
转化为lambda函数,如下所示:
j=lambda x,y:''.join(eval('y.remove(i);i*2')if i in y else i for i in x)
在这两个x
中都有一个字符串,如“拟声词”
,y
是一个列表,如['o','a','o']
但由于某种原因,它返回一个语法错误。有人能解释一下吗?我非常喜欢你的功能,但这可以满足你的需要
from itertools import chain
j = lambda x, y: ''.join(filter(None,chain.from_iterable((i * 2,y.remove(i)) if i in y else i for i in x)))
print(j("'onomatopoeia'",['o','a','o']))
'oonoomaatopoeia'
首先,由于循环中的副作用,您可能不应该用lambda重写它。如果你真的想这样做,不要使用评估 我建议:
j = lambda x, y: ''.join((y.remove(i) or 2 * i) if i in y else i for i in x)
因为remove的结果是None
,所以或
的第二个参数将是结果。这避免了评估。但比for循环更糟糕
如在对原始问题的评论中所述,
2*y.pop(y.index(i))
比或
结构更具可读性。您将在y
上循环两次,但性能似乎不是问题。如果您想编写好的函数表达式(使用lambda
s、map
、reduce
、filter
等),应该避免副作用
我强烈希望你的代码是一个函数,而不是一个有副作用的lambda
这是一个lambda表达式中的无副作用实现:
>>> from functools import reduce
>>> (lambda x, y: reduce(lambda a, b: \
... (a[0]+2*b, a[1][:a[1].index(b)]+a[1][a[1].index(b)+1:]) if b in a[1] \
... else (a[0]+b, a[1]), x, ('',y))[0])('onomatopoeia', ['o','a','o'])
'oonoomaatopoeia'
恐怕它既不短,也不漂亮,也不容易理解,因为人们希望它是一只羔羊<代码>:/(希望有人能提出改进建议)
这只是一个反例,不鼓励在此上下文中使用lambda
在python中,lambdas最大的问题是没有像标准ML中那样的where
语法来定义同一表达式中的变量别名。所以,对于任何非琐碎的事情,事情都会很快变得丑陋
如果您想了解它的功能,可以使用reduce来运行自动机,其中(每一步)的结果就是计算的“状态” 初始“状态”是
(“”,['o','a','o'])
,reduce函数将根据需要从“拟声词”开始进行替换
这就是“国家”的演变:
我们只取最后一个状态的第一个元素。x
和y的值是多少?你到底为什么要这样做?预期的输出是什么oonoomaatopoeia
?也许他正在寻找一种使用lambdaI实现这一点的漂亮方法。他同意其他人的观点,即你不应该这样做,但如果你这样做,至少不要使用eval。您可以简单地使用y.pop(y.index(i))+i
或2*y.pop(y.index(i))
代替您的eval调用。顺便说一句,我怀疑您对性能感兴趣,但由于您逐个删除列表中的所有元素,因此该算法效率相当低;一个更快的选择是使用集合。计数器并减少字母的计数。为什么不简单地''。加入(2*y.pop(y.index(i)),如果我在y中,否则i代表i在x中)
?@l4mpi,因为我使用的是OP自己的代码,索引的成本也并不比过滤好。如果由我决定,我不会使用这两种方法。我同意这两种方法都不是真正可行的方法,但是pop
变体在我看来更具可读性。我怀疑速度是一个问题,如果是这样的话,完全取消remove
调用可能是最好的做法(例如,使用计数器
并减少字母计数)。@l4mpi,正如我所说,我使用的是OP提供的代码,并使其按规定工作,但没有提供我个人使用的方式。'.join(2*y.pop(y.index(I)),如果我在y中,否则I代表I在x中)
我也不会使用
( '', ['o','a','o'] ) 'o'
( 'oo', ['a','o'] ) 'n'
( 'oon', ['a','o'] ) 'o'
( 'oonoo', ['a'] ) 'm'
( 'oonoom', ['a'] ) 'a'
( 'oonoomaa', [] ) 't'
( 'oonoomaat', [] ) 'o'
( 'oonoomaato', [] ) 'p'
( 'oonoomaatop', [] ) 'o'
( 'oonoomaatopo', [] ) 'e'
( 'oonoomaatopoe', [] ) 'i'
( 'oonoomaatopoei', [] ) 'a'
( 'oonoomaatopoeia', [] )