[Python-ideas] while conditional in list comprehension ??

Oscar Benjamin oscar.j.benjamin at gmail.com
Tue Jan 29 02:02:31 CET 2013


On 28 January 2013 23:27, Terry Reedy <tjreedy at udel.edu> wrote:
> On 1/28/2013 8:33 AM, Wolfgang Maier wrote:
>>
>> Dear all,
>> I guess this is so obvious that someone must have suggested it before:
>
> No one who understands comprehensions would suggest this.

That's a little strong.

>
>> in list comprehensions you can currently exclude items based on the if
>> conditional, e.g.:
>>
>> [n for n in range(1,1000) if n % 4 == 0]
>>
>> Why not extend this filtering by allowing a while statement in addition to
>> if, as in:
>
>
> Why not? Because it is flat-out wrong. Or if you prefer, nonsensical. You
> want to break, not filter; and you are depending on the order of the items
> from the iterator. Comprehensions are a math-logic idea invented for
> (unordered) sets and borrowed by computer science and extended to sequences.
> However, sequences do not replace sets.

Python's comprehensions are based on iterators that are inherently
ordered (although in some cases the order is arbitrary). In the most
common cases the comprehensions produce lists or generators that
preserve the order of the underlying iterable. I find that the cases
where the order of an iterable is relevant are very common in my own
usage of iterables and of comprehensions.

>
> https://en.wikipedia.org/wiki/Set-builder_notation
> https://en.wikipedia.org/wiki/List_comprehension
>
> Python has also extended the idea to dicts and iterators and uses almost
> exactly the same syntax for all 4 variations.

Although dicts and sets should be considered unordered they may still
be constructed from a naturally ordered iterable. There are still
cases where it makes sense to define the construction of such an
object in terms of an order-dependent rule on the underlying iterator.

>
>> [n for n in range(1,1000) while n < 400]
>
> This would translate as
>
> def _temp():
>   res = []
>   for n in range(1, 1000):
>     while n < 400):
>       res.append(n)
>   return res
> _temp()

I guess this is what you mean by "No one who understands
comprehensions would suggest this." Of course those are not the
suggested semantics but I guess from this that you would object to a
while clause that had a different meaning.

> which makes an infinite loop, not a truncated loop.
> What you actually want is
>
>   res = []
>   for n in range(1, 1000):
>     if >= 400): break
>     res.append(n)
>
> which is not the form of a comprehension.

The form of a comprehension is not unchangeable.


Oscar



More information about the Python-ideas mailing list