Assertion in list comprehension

Stargaming stargaming at
Wed Aug 1 18:55:53 CEST 2007

On Wed, 01 Aug 2007 11:28:48 -0500, Chris Mellon wrote:

> On 8/1/07, beginner <zyzhu2000 at> wrote:
>> Hi,
>> Does anyone know how to put an assertion in list comprehension? I have
>> the following list comprehension, but I want to use an assertion to
>> check the contents of rec_stdl. I ended up using another loop which
>> essentially duplicates the functions of list comprehension. It just
>> look like a waste of coding and computer time to me.
>> I just wish I could put the assertions into list comprehensions.
>>         x=[(rec_stdl[0].st/10000.0,
>>             rec_stdl[0].cl,
>>             rec_stdl[0].bb,
>>             rec_stdl[0].bo,
>>             rec_stdl[1].bb,
>>             rec_stdl[1].bo,
>>             rec_stdl[0].ex
>>            )
>>            for rec_stdl in rec_by_ex if len(rec_stdl)==2
>>         ]
>>         #duplicated loop
>>         if __debug__:
>>             for rec_stdl in rec_by_ex:
>>                 l=len(rec_stdl)
>>                 assert(l<=2 and l>0)
>>                 if l==2:
>>                     assert(rec_stdl[0].c=="C" and rec_stdl[1].c=="P")
>>                     assert(rec_stdl[0].ex==rec_stdl[1].ex)
>>                     assert(rec_stdl[0].st==rec_stdl[1].st)
>>                     assert(rec_stdl[0].cp==rec_stdl[1].cp)
> First: All your asserts are wrong. Assert is a statement, not a
> function. These specific ones will behave as expected, but it's easy to
> accidentally write ones that always pass this way.

Could you come up with an example? I can only think of accidentally 
injecting a comma, what would create a (true, in a boolean context) tuple.

And, well, if you're only using () for readabilty, this might sometimes 
look messy when calling assert with the extended syntax::

  assert(False), "error text"

Where one could expect the construction of a tuple.

> Secondly: This is a waste of code, because if __debug__ is not defined
> asserts will be skipped by the compiler. You could use the same loop
> block for both branches.

Well, the `assert` isn't there for no reason, but if you're serious about 
it, `raise` could be better.

> Thirdly: This sort of testing is precisely what unit tests and/or
> doctests are for.

Huh? What beginner is doing there seems more like input validation than 
testing. Unit or doctests are meant for testing (and in case of doctests, 
showing) whether a function works as expected.

More information about the Python-list mailing list