List Partition Comprehension (Feature Suggestion)

Terry Reedy tjreedy at udel.edu
Tue Sep 22 23:09:20 EDT 2020


On 9/22/2020 3:16 PM, Yakov Shalunov wrote:
> Python list comprehension is substantially faster than plan iteration, to the point where
> ```
> l0, l1 = [],[]
> for x in l:
>      if cond(x):
>          l0.append(x)
>      else:
>          l1.append(x)
> ```
> runs at about the same speed as
> ```
> l0 = [x for x in l if cond(x)]
> l1 = [x for x in l if not cond(x)]
> ```
> assuming `cond` is a computationally light conditional.
> While this isn't an extremely common use, I suggest a "partition comprehension" syntax which extends normal filtered-generator syntax. Such as:
> ```
> l0, l1 = ([x for x in l if cond(x) else x])
> ```
> (parenthesis there to indicate that the output is a tuple)

Parentheses only make a tuple when empty.  They otherwise group items as 
function arguments or to indicate precedence.

'else' by itself would be enough to indicate that one wants two streams, 
even if it is a bit baroque.

'x for x in iterable if condition' is a generator comprehension. 
Putting {} or [] around it says to run the iteration to make a set or 
list.  Passing the generator comprehension to set() or list() has the 
same effect, but the set or list comprehensions can be optimized to run 
faster.

'x:f(x) for x in iterable' is not quite legal as a standalone generator, 
but '(x,f(x)} for x in iterable' is, and {x:f(x) for x in iterable} has 
the effect of
dict((x,f(x)) for x in iterable).

By analogy,
'ftrue(x) for x in iterable if condition else ffalse(x)'
should be a double generator comprehension producing a pair of generators
'(f(x) for x in iterable if condition),
  (f(x) for x in iterable if not condition)'

Then enclosing in {} or [] applies set() or list() to each separately to 
produce a pair of sets or lists.  But the latter could be optimized.

The double generator comprehension is similar to a conditional 
expression except that both true and false values are produced -- and 
kept separate.
'(ft(x) if condition else ff(x)) for x in iterable'
is legal today, but does not separate the true and false results.

-- 
Terry Jan Reedy



More information about the Python-list mailing list