[Python-ideas] Map-then-filter in comprehensions
Chris Angelico
rosuav at gmail.com
Tue Mar 8 15:16:21 EST 2016
On Wed, Mar 9, 2016 at 7:06 AM, Pavol Lisy <pavol.lisy at gmail.com> wrote:
> 2016-03-08 15:17 GMT+01:00, Allan Clark <allan.clark at gmail.com>:
> [...]
>> [y for x in numbers if abs(x) as y > 5]
> [...]
>> * It would need to be decided whether you allowed multiple 'as'
>> expression in the condition, particularly using 'and' or 'or' as in 'if
>> f(a) as x > 5 and f(b) as y > 5'
>
> Just small idea not to forget here:
>
> [y+z for x in numbers if abs(x) as y > 5 or x**2 as z>100]
>
> "or" is short-circuit operator so z could be not (well) defined.
Enforcing that the order of operations is as you're implying:
[y+z for x in numbers if (abs(x) as y) > 5 or (x**2 as z) > 100]
If the first condition is true, the second will not be evaluated.
It'll be equivalent to:
def <listcomp>():
result = []
for x in numbers:
y = abs(x)
if y > 5:
result.append(y+z)
else:
z = x**2
if z > 100: result.append(y+z)
return result
So, yeah, that could surprise a *lot* of people. Either an
UnboundLocalError, or retaining the value from the previous iteration.
Recommendation: If you use name bindings in the second half, use
bitwise operators instead:
[y+z for x in numbers if (abs(x) as y) > 5 | (x**2 as z) > 100]
That'll force both sides to be evaluated. (Downside: It's reliable
only if you actually have True and False.)
ChrisA
More information about the Python-ideas
mailing list