Which is more Pythonic?

Terry Reedy tjreedy at udel.edu
Wed Apr 1 23:15:01 EDT 2009


John Machin wrote:
> On Apr 2, 2:10 am, John Posner <jjpos... at snet.net> wrote:
>> Dennis Lee Bieber presented a code snippet with two consecutive statements
>> that made me think, "I'd code this differently". So just for fun ... is
>> Dennis's original statement or my "_alt" statement more idiomatically
>> Pythonic? Are there even more Pythonic alternative codings?
>>
>>    mrkrs = [b for b in block
>>      if b > 127
>>        or b in [ "\r", "\n", "\t" ]       ]
> 
> I'd worry about "correct" before "Pythonic" ... see my responses to
> Dennis in the original thread.
> 
>>    mrkrs_alt1 = filter(lambda b: b > 127 or b in [ "\r", "\n", "\t" ],
>> block)
>>    mrkrs_alt2 = filter(lambda b: b > 127 or b in list("\r\n\t"), block)

Comprehensions combine map and filter and somewhat, to some people, 
replace both.  Tastes vary.

If one has a filter function f already, filter(f,seq) may be faster than 
(f(i) for i in seq).  If one does not, (<expression involving i> for i 
in seq) will probably be faster than filter(lambda i: <expression 
imvolving i>, seq) as it avoids a function call, using inlined 
expression code.

So either can be more Pythonic, depending on the context.

> Try this on and see if it fits:
> 
> num_bin_chars = sum(b > "\x7f" or b < "\x20" and b not in "\r\n\t" for
> b in block)

However, for just counting, this is even better -- and most Pythonic! 
In fact, being able to count the number of True values in a stream of 
True and False by summation is part of the justification of bool being a 
subclass of int.

>> (Note: Dennis's statement converts a string into a list; mine does not.)
> 
> What is list("\r\n\t") doing, if it's not (needlessly) converting a
> string into a list?
> 
>> ---
>>
>>    binary = (float(len(mrkrs)) / len(block)) > 0.30
>>
>>    binary_alt = 1.0 * len(mrkrs) / len(block) > 0.30
>>
> 
> num_bin_chars > 0.30 * len(block)
> 
> (no mucking about with float() or 1.0, and it doesn't blow up on a
> zero-length block)

Nice point!

Terry Jan Reedy




More information about the Python-list mailing list