Not x.islower() has different output than x.isupper() in list output...

Stephen Hansen me at ixokai.io
Fri Apr 29 21:29:57 EDT 2016


On Fri, Apr 29, 2016, at 06:17 PM, Christopher Reimer wrote:
> Greetings,
> 
> I was playing around with a piece of code to remove lowercase letters 
> and leave behind uppercase letters from a string when I got unexpected 
> results.
> 
>      string = 'Whiskey Tango Foxtrot'
> 
>      list(filter((lambda x: not x.islower()), string))
> 
>      ['W', ' ', 'T', ' ', 'F']
> 
> Note the space characters in the list.
> 
>      list(filter((lambda x: x.isupper()), string))
> 
>      ['W', 'T', 'F']
> 
> Note that there are no space characters in the list.
> 

> Shouldn't the results between 'not x.islower()' and 'x.isupper()' be 
> identical?

Absolutely not. There are characters which are neither uppercase or
lowercase: specifically, whitespace in your situation. 

"x.islower()" is true for everything that is lowercase, and false for
everything else. (Including things which have no case). If you invert
with not, then its false for everything that is lowercase, but true for
everything else: including things which have no case.

"x.isupper()" is true for everything that is uppercase, and false for
everything else. This is therefore a narrower test then "not
x.islower()"

x.isupper() is a narrower, more specific test then "not x.islower()". If
you used "not x.isupper()" you'd get the whitespace in it too (along
with all the lower case characters). 

If isupper/islower were perfect opposites of each-other, there'd be no
need for both. But since characters can be upper, lower, or *neither*,
you run into this situation. 

-- 
Stephen Hansen
  m e @ i x o k a i  . i o



More information about the Python-list mailing list