[Python-ideas] while conditional in list comprehension ??
Oscar Benjamin
oscar.j.benjamin at gmail.com
Tue Jan 29 02:34:46 CET 2013
On 29 January 2013 01:12, Ian Cordasco <graffatcolmingov at gmail.com> wrote:
> On Mon, Jan 28, 2013 at 8:02 PM, Oscar Benjamin
> <oscar.j.benjamin at gmail.com> wrote:
>>
>> 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.
I was referring to the case of constructing an object that does not
preserve order by iterating over an object that does. Clearly a while
clause would be a lot less useful if you were iterating over an object
whose order was arbitrary: so don't use it in that case.
A (contrived) example - caching Fibonacci numbers:
# Fibonacci number generator
def fib():
a = b = 1
while True:
yield a
a, b = b, a+b
# Cache the first N fibonacci numbers
fib_cache = {n: x for n, x in zip(range(N), fib())}
# Alternative
fib_cache = {n: x for n, x in enumerate(fib()) while n < N}
# Cache the Fibonacci numbers less than X
fib_cache = {}
for n, x in enumerate(fib()):
if x > X:
break
fib_cache[n] = x
# Alternative 1
fib_cache = {n: x for n, x in enumerate(takewhile(lambda x: x < X, fib()))}
# Alternative 2
fib_cache = {n: x for n, x in enumerate(fib()) while x < X}
Oscar
More information about the Python-ideas
mailing list