29

Say I have a string that can contain different characters:

e.g. word = "UPPER£CASe"

How would I test the string to see if all the characters are uppercase and no other punctuation, numbers, lowercase letters etc?

Georgy
  • 12,464
  • 7
  • 65
  • 73
ffgghhffgghh
  • 319
  • 1
  • 3
  • 7

6 Answers6

45

You should use str.isupper() and str.isalpha() function.

Eg.

is_all_uppercase = word.isupper() and word.isalpha()

According to the docs:

S.isupper() -> bool

Return True if all cased characters in S are uppercase and there is at least one cased character in S, False otherwise.

Lord Elrond
  • 13,430
  • 7
  • 40
  • 80
Yash Mehrotra
  • 3,032
  • 1
  • 21
  • 24
  • This also shows True if it contains a number or punctuation mark for example. I need it so it is only uppercase letters (A-Z). Thanks – ffgghhffgghh Nov 24 '15 at 00:57
  • Be aware that this is does not restrict to ASCII characters, it will allow uppercase Greek and Cyrilic for example. Which may or may not be what you want. – MestreLion Apr 12 '21 at 17:01
  • 1
    This yields `True` for "ΓΔΘΞΠΦΨΩБГДЖЙЛ", so beware. Well, they are uppercase letters.. just not English ones. – MestreLion Apr 12 '21 at 17:22
7

You could use regular expressions:

all_uppercase = bool(re.match(r'[A-Z]+$', word))
Luke Yeager
  • 1,400
  • 1
  • 17
  • 30
  • This also shows True if it contains a number or punctuation mark for example. I need it so it is only uppercase letters (A-Z). Thanks – ffgghhffgghh Nov 24 '15 at 00:50
4

Yash Mehrotra has the best answer for that problem, but if you'd also like to know how to check that without the methods, for purely educational reasons:

import string

def is_all_uppercase(a_str):
    for c in a_str:
        if c not in string.ascii_uppercase:
            return False
    return True
Community
  • 1
  • 1
Diogo Martins
  • 917
  • 7
  • 15
1

Here you can find a very useful way to check if there's at least one upper or lower letter in a string

Here's a brief example of what I found in this link:

print(any(l.isupper() for l in palabra))

https://www.w3resource.com/python-exercises/python-basic-exercise-128.php

Ajay Sivan
  • 2,807
  • 2
  • 32
  • 57
STATECHRD
  • 11
  • 2
0

You can alternatively work at the level of characters.

The following function may be useful not only for words but also for phrases:

def up(string):
    upper=[ch for ch in string if ch.isupper() or ch.isspace()]
    if len(upper)==len(string):
        print('all upper')
    else:
        print("some character(s) not upper")

strings=['UPPERCAS!', 'UPPERCASe', 'UPPERCASE', 'MORE UPPERCASES']
for s in strings:
   up(s)
Out: some character(s) not upper 
Out: some character(s) not upper
Out: all upper
Out: all upper
  • That's an incredibly inefficient code in every step: if you really want to use a character-level approach, instead of a list comprehension with a `len()` test that needlessly tests *all* chars even when the first fails, use a generator expression with `any()`/`all()` so it short-circuits on the first failed character. – MestreLion Apr 13 '21 at 02:16
0

Using the same approach taken by Diogo Martins, but using all() and a generator as an alternative to the for/if/return construct for a more elegant and pythonic solution:

import string
is_all_uppercase = all(c in string.ascii_uppercase for c in word)

It avoids scanning the string twice by testing each character only once, and it short-circuits on the first failed character.

Or, to optimize it further:

upper = set('ABCDEFGHIJKLMNOPQRSTUVWXYZ')

is_all_uppercase = all(c in upper for c in word)

However, for common inputs this does not perform better than the accepted solution word.isalpha() and word.isupper(): by using C-compiled builtin methods it beats any pure-python solution even if it scans the string twice:

$ python3 -m timeit -s 'word="UPPER£CASe"; upper=set("ABCDEFGHIJKLMNOPQRSTUWXYZ")' -- \
'all(c in upper for c in word)'
1000000 loops, best of 3: 0.514 usec per loop

$ python3 -m timeit -s 'word="UPPER£CASe"' -- 'word.isupper() and word.isalpha()'
10000000 loops, best of 3: 0.0446 usec per loop

Please note that str.isupper() and str.isalpha() includes Unicode characters such as Greek, Cyrilic ("russian"), Arabic, etc. As long as they're uppercase ;-)

>>> word = "ΓΔΘΞΠΦΨΩБГДЖЙЛ"; word.isupper() and word.isalpha()
True
MestreLion
  • 12,698
  • 8
  • 66
  • 57