How do you have a multiple line statement in either a list comprehension or eval?
I was trying to turn this code:
def f(x, y, b=''):
for i in x:
if i in y:
y.remove(i)
i *= 2
b += i
return b
Into a lambda function like so:
j=lambda x,y:''.join(eval('y.remove(i);i*2')if i in y else i for i in x)
In both x
is a string such as 'onomatopoeia'
and y
is a list such as ['o','a','o']
.
But for some reason, it returns a syntax error. Can anyone explain this?
First, you probably shouldn't rewrite this with a lambda because of the side-effects in the loop. If you really want to anyway, don't use an eval.
I'd suggest:
j = lambda x, y: ''.join((y.remove(i) or 2 * i) if i in y else i for i in x)
Because the result of remove is None
the second argument to or
will be the result. This avoids the eval. But it's still worse then a for-loop.
As noted in comments on the original question, 2 * y.pop(y.index(i))
is more readable than the or
construct. You'll loop twice over y
, but performance doesn't seem the issue.
I would vastly prefer your function but this will do what you want.
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'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With