I want to know if all words in the list are all capitalized, that is, all alphabetical characters are capitalized.
I tried this for a simple string to understand behavior of isupper()
:
>>> 'FDSFS BBIBIFBIBWEF ASDASD 112,32:/'.isupper()
True
So I separated words in that sentence into list:
>>> sent = ['FDSFS','BBIBIFBIBWEF','ASDASD', '112','32:/']
>>> all([word.isupper() for word in sent])
False
So I checked the what was argument list to all()
contained:
>>> [word.isupper() for word in sent]
[True, True, True, False, False]
Weirdly, isupper()
returns False
for strings containing no alphabets (that is made up of only numbers and special characters), but returns True
if those strings are made to contain even a single capital character:
>>> '123'.isupper()
False
>>> '123A'.isupper()
True
>>> '123?A'.isupper()
True
>>> '123?'.isupper()
False
>>> ''.isupper()
False
Q1. Is there any design decision behind this behavior for isupper()
?
Q2. How can I achieve what I want to do in the most pythonic and minimal way? (Maybe there is any other function that just checks if all alphabetical words in the input string are capital and don't bother about special characters, numbers, and empty strings at all? Or do I have to write one from scratch?)
As mentioned in the docs:
Return
True
if all cased characters in the string are uppercase and there is at least one cased character,False
otherwise.
As you can see, it is checking if all characters in the string are uppercase not just the letters.
It's a similar implementation as this:
import string
def upper(s):
notlower = all([word not in string.ascii_lowercase for word in s])
anyupper = any([word in string.ascii_uppercase for word in s])
return notlower and anyupper
print(upper(s))
Solution 1:
The way to solve this might be to use upper
and check if it is equivalent to the original string:
>>> sent = ['FDSFS','BBIBIFBIBWEF','ASDASD', '112','32:/']
>>> all([word.upper() == word for word in sent])
True
>>>
Solution 2:
Or check if it's none of the characters are lowercase:
>>> sent = ['FDSFS','BBIBIFBIBWEF','ASDASD', '112','32:/']
>>> all([(not word.islower()) for word in sent])
True
>>>
Just realized @DaniMesejo posted this, credit to him.
Solution 3:
This could be done very elegantly with regex too:
>>> import re
>>> sent = ['FDSFS','BBIBIFBIBWEF','ASDASD', '112','32:/']
>>> expr = re.compile('^[^a-z]*$')
>>> all(map(expr.search, sent))
True
>>>
With map
and a compiled regular expression, might be more efficient.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With