On 29 January 2013 01:12, Ian Cordasco <graffatcolmingov@gmail.com> wrote:
On Mon, Jan 28, 2013 at 8:02 PM, Oscar Benjamin <oscar.j.benjamin@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