On Mon, Jan 28, 2013 at 8:02 PM, Oscar Benjamin <oscar.j.benjamin@gmail.com> wrote:
On 28 January 2013 23:27, Terry Reedy <tjreedy@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.
Technically they are not inherently ordered. You give the perfect example below.
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.
They may be, but they may also be constructed from an unordered iterable. How so? Let `d` be a non-empty dictionary, and `f` a function that defines some mutation of it's input such that there doesn't exist x such that x = f(x). e = {k: f(v) for k, v in d.items()} You're taking an unordered object (a dictionary) and making a new one from it. An order dependent rule here would not make sense. Likewise, if we were to do: e = [(k, f(v)) for k, v in d.items()] We're creating order from an object in which there is none. How could the while statement be useful there? An if statement works fine. A `while` statement as suggested wouldn't.
[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.
They are not the suggested semantics. You are correct. But based upon how list comprehensions are currently explained, one would be reasonable to expect a list comprehension with `while` to operate like this.
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.
Agreed it is definitely mutable. I am just of the opinion that this is one of those instances where it shouldn't be changed.