Capitalization of each sentence in a string in Python 3


This should be easy but somehow I'm not quite getting it.

My assignment is:


Write a function sentenceCapitalizer that has one parameter of type string. The function returns a copy of the string with the first character of each sentence capitalized. The function should return “Hello. My name is Joe. What is your name?” if the argument to the function is “hello. my name is Joe. what is your name?” Assume a sentence is separated by a period followed by a space."


What I have so far is:

def sentenceCapitalizer (string1: str): words = string1.split(". ") words2=words.capitalize() string2=words2.join() return (string2) print (sentenceCapitalizer("hello. my name is Joe. what is your name?"))

Upon execution I get the error:

Traceback (most recent call last): File "C:\Users\Andrew\Desktop\lab3.py", line 83, in <module> print (sentenceCapitalizer("hello. my name is Joe. what is your name?")) File "C:\Users\Andrew\Desktop\lab3.py", line 79, in sentenceCapitalizer words2=words.capitalize() AttributeError: 'list' object has no attribute 'capitalize'"

What is that telling me and how do I fix this? I tried following instructions found on a page listed as the python software foundation so I thought I'd have this.


You are trying to use a string method on the wrong object; words is list object <em>containing</em> strings. Use the method on each individual element instead:

words2 = [word.capitalize() for word in words]

But this would be applying the <em>wrong</em> transformation; you don't want to capitalise the whole sentence, but <em>just</em> the first letter. str.capitalize() would lowercase <em>everything else</em>, including the J in Joe:

>>> 'my name is Joe'.capitalize() 'My name is joe'

Limit yourself to the <em>first letter only</em>, and then add back the rest of the string unchanged:

words2 = [word[0].capitalize() + word[1:] for word in words]

Next, a list object has no .join() method either; that too is a string method:

string2 = '. '.join(words2)

This'll join the strings in words2 with the '. ' (full stop and space) joiner.

You'll probably want to use better variable names here; your strings are sentences, not words, so your code could do better reflecting that.

Together that makes your function:

def sentenceCapitalizer (string1: str): sentences = string1.split(". ") sentences2 = [sentence[0].capitalize() + sentence[1:] for sentence in sentences] string2 = '. '.join(sentences2) return string2


>>> def sentenceCapitalizer (string1: str): ... sentences = string1.split(". ") ... sentences2 = [sentence[0].capitalize() + sentence[1:] for sentence in sentences] ... string2 = '. '.join(sentences2) ... return string2 ... >>> print (sentenceCapitalizer("hello. my name is Joe. what is your name?")) Hello. My name is Joe. What is your name?


This does the job. Since it extracts all sentences including their trailing whitespace, this also works if you have multiple paragraphs, where there are line breaks between sentences.

import re def sentence_case(text): # Split into sentences. Therefore, find all text that ends # with punctuation followed by white space or end of string. sentences = re.findall('[^.!?]+[.!?](?:\s|\Z)', text) # Capitalize the first letter of each sentence sentences = [x[0].upper() + x[1:] for x in sentences] # Combine sentences return ''.join(sentences)

Here is a <a href="http://ideone.com/fvTezY" rel="nofollow">working example</a>.


To allow arbitrary whitespace after the dot. Or to capitalize the full words (It might make the difference for a Unicode text), you could <a href="https://docs.python.org/3/library/re.html" rel="nofollow">use regular expressions -- re module</a>:

#!/usr/bin/env python3 import re def sentenceCapitalizer(text): return re.sub(r"(\.\s+|^)(\w+)", lambda m: m.group(1) + m.group(2).capitalize(), text) s = "hEllo. my name is Joe. what is your name?" print(sentenceCapitalizer(s)) # -> 'Hello. My name is Joe. What is your name?'

Note: pep8 recommends lowercase names for functions e.g., capitalize_sentence() instead of sentenceCapitalizer().

To accept a larger variaty of texts, you could <a href="http://www.nltk.org/book/ch00.html" rel="nofollow">use nltk package</a>:

# $ pip install nltk from nltk.tokenize import sent_tokenize, word_tokenize def sent_capitalize(sentence): """Capitalize the first word in the *sentence*.""" words = word_tokenize(sentence) if words: words[0] = words[0].capitalize() return " ".join(words[:-1]) + "".join(words[-1:]) # dot text = "hEllo. my name is Joe. what is your name?" # split the text into a list of sentences sentences = sent_tokenize(text) print(" ".join(map(sent_capitalize, sentences))) # -> Hello. My name is Joe. What is your name?


I did not use 'split' but just while loop instead. Here is my code.

my_string = input('Enter a string: ') new_string = '' new_string += my_string[0].upper() i = 1 while i < len(my_string)-2: new_string += my_string[i] if my_string[i] == '.' or my_string[i] == '?' or my_string[i] == '!': new_string += ' ' new_string += my_string[i+2].upper() i = i+3 else: if i == len(my_string)-3: new_string += my_string[len(my_string)-2:len(my_string)] i = i+1 print(new_string)

Here is how it works:

Enter a string: hello. my name is Joe. what is your name? Hello. My name is Joe. What is your name


Just because I couldn't find this solution here.

You can use 'sent_tokenize' method from nltk.

import nltk string = "hello. my name is Joe. what is your name?" sentences = nltk.sent_tokenize(string) print (' '.join([s.replace(s[0],s[0].capitalize(),1) for s in sentences]) )

And the output

Hello. My name is Joe. What is your name?


  • what happens to finally block in the following cases?
  • Python Floating Point Formatting
  • Compact framework voice recognize API or library
  • AutoHotKey - how to send control and same key multiple times
  • disablinging autorecover option for powepoint
  • Edit assembly language code in Visual Studio while stepping through each statement
  • Can I update/select from a table in one query?
  • Upgrade project from WorkLight 6.1 to MobileFirst 7.1
  • Tools for understanding HTML layout
  • F#: In which memory area is the continuation stored: stack or heap?
  • Python 3.2.2, error(scripts to exe)
  • Synchronize windows folders
  • import scipy.sparse failed
  • How to make R's read_csv2() recognise the text characters properly
  • configure: error: no acceptable C compiler found in $PATH
  • During installation of Django, why do I keep getting ImportError: No module named django?
  • where do I find the xml.dom python package for the python-2.6.0-8.9.28 and I have a suse/x86_64 vers
  • Python pickle not one-to-one: different pickles give same object
  • pillow imaging ImportError
  • Debugging VB6 Code From Visual Studio 2010
  • Automatically associate new Sonar project with custom quality profile and quality gate
  • Eclipse CDT error: Unable to compile
  • Django simple Captcha “No module named fields” error
  • why xml file does not aligned properly after append the string in beginning and end of the file usin
  • How to know when stdin is empty if it contains EOF?
  • HTML download movie download link
  • Bug in WPF DataGrid
  • TFS: Get latest causes slow project reloading
  • Javascript Callbacks with Object constructor
  • htaccess rewriting URLs with multiple forward slashes
  • Display Images one by one with next and previous functionality
  • How to make Safari send if-modified-since header?
  • Web-crawler for facebook in python
  • AT Commands to Send SMS not working in Windows 8.1
  • php design question - will a Helper help here?
  • A cron job substitute?
  • Rails 2: use form_for to build a form covering multiple objects of the same class
  • NSLayoutConstraint that would pin a view to the bottom edge of a superview
  • How do I configure my settings file to work with unit tests?
  • Is it possible to post an object from jquery to bottle.py?