Count the uppercase letters in a string with Python

Question:

I am trying to figure out how I can count the uppercase letters in a string.

I have only been able to count lowercase letters:

def n_lower_chars(string):
    return sum(map(str.islower, string))

Example of what I am trying to accomplish:

Type word: HeLLo                                        
Capital Letters: 3

When I try to flip the function above, It produces errors:

def n_upper_chars(string):
    return sum(map(str.isupper, string))
Asked By: Stevenson

||

Answers:

You can do this with sum, a generator expression, and str.isupper:

message = input("Type word: ")

print("Capital Letters: ", sum(1 for c in message if c.isupper()))

See a demonstration below:

>>> message = input("Type word: ")
Type word: aBcDeFg
>>> print("Capital Letters: ", sum(1 for c in message if c.isupper()))
Capital Letters:  3
>>>
Answered By: user2555451
from string import ascii_uppercase
count = len([letter for letter in instring if letter in ascii_uppercase])

This is not the fastest way, but I like how readable it is. Another way, without importing from string and with similar syntax, would be:

count = len([letter for letter in instring if letter.isupper()])
Answered By: mr2ert

Using len and filter :

import string
value = "HeLLo Capital Letters"
len(filter(lambda x: x in string.uppercase, value))
>>> 5
Answered By: njzk2

You can use re:

import re
string = "Not mAnY Capital Letters"
len(re.findall(r'[A-Z]',string))

5

Answered By: Tapo4ek

The (slightly) fastest method for this actually seems to be membership testing in a frozenset

import string
message='FoObarFOOBARfoobarfooBArfoobAR'
s_upper=frozenset(string.uppercase)

%timeit sum(1 for c in message if c.isupper())
>>> 100000 loops, best of 3: 5.75 us per loop

%timeit sum(1 for c in message if c in s_upper)
>>> 100000 loops, best of 3: 4.42 us per loop
Answered By: benbo

This works

s = raw_input().strip()
count = 1
for i in s:
    if i.isupper():
        count = count + 1
print count
Answered By: Samueltommzy

I’ve done some comparisons of the methods above + RE compiled using
Python 3.7.4
For this, I’ve used the book Alice’s Adventures in Wonderland, by Lewis Carroll from Project Gutenberg.

from urllib.request import urlopen

# Download 
text = urlopen('https://www.gutenberg.org/files/11/11-0.txt').read().decode('utf-8')
# Split it into the separate chapters and remove table of contents, etc
sep = 'CHAPTER'
chaps = [sep + ch for ch in text.split('CHAPTER') if len(ch) > 1000]
len(chaps)

Defined all approaches as functions in order to use them in the loop and keep succinct.

import re
import string

def py_isupper(text): 
    return sum(1 for c in text if c.isupper())

def py_str_uppercase(text):
    return sum(1 for c in text if c in string.ascii_uppercase)

def py_filter_lambda(text):
    return len(list(filter(lambda x: x in string.ascii_uppercase, text)))

def regex(text):
    return len(re.findall(r'[A-Z]',text))

# remove compile from the loop
REGEX = re.compile(r'[A-Z]')
def regex_compiled(text):
    return len(REGEX.findall(text))

The results are below.

%%timeit
cnt = [py_isupper(ch) for ch in chaps]

7.84 ms ± 69.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%%timeit
cnt = [py_str_uppercase(ch) for ch in chaps]

11.9 ms ± 94.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%%timeit
cnt = [py_filter_lambda(ch) for ch in chaps]

19.1 ms ± 499 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%%timeit
cnt = [regex(ch) for ch in chaps]

1.49 ms ± 13 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%%timeit
cnt = [regex_compiled(ch) for ch in chaps]

1.45 ms ± 8.69 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Answered By: Nikita
def n_lower_chars(string):
    return sum(i.isupper() for i in string)

sums up the numbers of True values in the generator expression

Answered By: projectpenguin