list comprehension question

Tim Peters tim.one at comcast.net
Mon Mar 25 15:15:23 EST 2002


[Tim]
> No.  len([f(x) for x in y]) == len(y) whenever no exception occurs,
> regardless of the form of f() or type of y.

[Neil Schemenauer]
> Looks like the bot needs a bugfix:

Nope, an exception occurs in your example when evaluating

    len([f(x) for x in f()]) == len(f())

and the bot refused to say anything about what happens then (I confirmed
that this was intentional, and he was quite irked (for a bot) that I
questioned him on this point).  As you show below, one also occurs when a
non-bot human substitutes len(f), which is a different expression entirely.
Also not covered are cases where len(y) returns an object that raises an
exception when "==" tries to compare it.

>     >>> def f():
>     ...   for x in range(10):
>     ...     yield x
>     ...
>     >>> len(f)
>     Traceback (most recent call last):
>       File "<stdin>", line 1, in ?
>     TypeError: len() of unsized object
>     >>> len([int(x) for x in f()])
>     10
>
> Hmm, should len() should work on pure iterators?

I don't think so (the bot has no opinion on this, btw), and deliberately
left len() alone when generalizing "sequence contexts" for 2.2.  __len__ is
best thought of as a functional (no side-effect) method of sequences nd
mappings, and there's generally no reason to suppose that len(iterable)
wouldn't be destructive -- the iterator protocol doesn't have any notion of
resetting, and some iterators can't be restarted.  So the potential for
suprise is high, and the few sane use cases are easily programmed
explicitly; e.g., len(list(f)), or a loop to drive the iterator and count
how many times it goes around.





More information about the Python-list mailing list