TIMEX
TIMEX

Reputation: 271584

How can I capitalize the first letter of each word in a string?

What’s the simplest way to transform this?

s = 'the brown fox'

s should be:

'The Brown Fox'

Upvotes: 869

Views: 1010403

Answers (24)

steveha
steveha

Reputation: 76695

Here are two more ways:

  1. Split into words, initial-cap each word from the split groups, and rejoin. This will change the white space separating the words into a single white space, no matter what it was.

    For example, using a list comprehension:

    s = 'the brown fox'
    lst = [word[0].upper() + word[1:] for word in s.split()]
    s = " ".join(lst)
    

    Or a generator expression (which has special syntax support):

    s = 'the brown fox'
    s = ' '.join(word[0].upper() + word[1:] for word in s.split())
    
  2. Use a regular expression to match the beginning of the string, or white space separating words, plus a single non-whitespace character; use parentheses to mark "match groups". Then use re.sub() to replace the patterns, passing it a function that returns the appropriate translated result for each match:

    import re
    s = 'the brown fox'
    
    def repl_func(m):
        return m.group(1) + m.group(2).upper()
    
    s = re.sub("(^|\s)(\S)", repl_func, s)
    

    This way produces the best result, because it avoids issues with punctuation and preserves the original whitespace and existing capitalization:

    >>> print(re.sub("(^|\s)(\S)", repl_func, "they're bill's  friends from\tthe UK"))
    They're Bill's  Friends From    The UK
    

Upvotes: 134

aljgom
aljgom

Reputation: 9129

Here is a summary of different ways to do it, and some pitfalls to watch out for. (Including when to use .title() or .capwords() and when they might not work)

The methods below will work for all these inputs:

""           => ""       
"a b c"      => "A B C"             
"foO baR"    => "FoO BaR"      
"foo    bar" => "Foo    Bar"   
"foo's bar"  => "Foo's Bar"    
"foo's1bar"  => "Foo's1bar"    
"foo 1bar"   => "Foo 1bar"     

These are the different methods:

  • Splitting the sentence into words and capitalizing the first letter then join it back together:

     # Be careful with multiple spaces, and empty strings
     # for empty words w[0] would cause an index error, 
     # but with w[:1] we get an empty string as desired
     def cap_sentence(s):
       return ' '.join(w[:1].upper() + w[1:] for w in s.split(' '))
    
  • Without splitting the string, checking blank spaces to find the start of a word

      def cap_sentence(s):
        return ''.join( (c.upper() if i == 0 or s[i-1] == ' ' else c) for i, c in enumerate(s) )
    
  • Or using generators:

      # Iterate through each of the characters in the string 
      # and capitalize the first char and any char after a blank space
      from itertools import chain 
      def cap_sentence(s):
        return ''.join( (c.upper() if prev == ' ' else c) for c, prev in zip(s, chain(' ', s)) )
    
  • Using regular expressions, from steveha's answer:

      # match the beginning of the string or a space, followed by a non-space
      import re
      def cap_sentence(s):
        return re.sub("(^|\s)(\S)", lambda m: m.group(1) + m.group(2).upper(), s)
    

Now, these are some other answers that were posted, and inputs for which they don't work as expected, if we define a word as being the start of the sentence or anything after a blank space:

  • .title()

      return s.title()
    
    # Undesired outputs: 
    "foO baR"    => "Foo Bar"     
    "foo's bar"  => "Foo'S Bar"   
    "foo's1bar"  => "Foo'S1Bar"       
    "foo 1bar"   => "Foo 1Bar"        
    

  • .capitalize() or .capwords()

      return ' '.join(w.capitalize() for w in s.split())    
    # or
      import string
      return string.capwords(s)
    
    # Undesired outputs:
    "foO baR"    => "Foo Bar"      
    "foo    bar" => "Foo Bar"      
    

    using ' ' for the split will fix the second output, but not the first

      return ' '.join(w.capitalize() for w in s.split(' '))    
    # or
      import string
      return string.capwords(s, ' ')
    
    # Undesired outputs:
    "foO baR"    => "Foo Bar"      
    

  • .upper()

    Be careful with multiple blank spaces, this gets fixed by using ' ' for the split (like shown at the top of the answer)

      return ' '.join(w[0].upper() + w[1:] for w in s.split())
    # Undesired outputs:
    "foo    bar" => "Foo Bar"                 
    

Upvotes: 52

Erick Mamberger
Erick Mamberger

Reputation: 127

If you will use the method .title(), then the letters after ' will also become uppercase. Like this:

>>> "hello world's".title()
"Hello World'S"

To avoid this, use the capwords function from the string library. Like this:

>>> import string
>>> string.capwords("hello world's")
"Hello World's"

Upvotes: 8

Haris
Haris

Reputation: 395

You can use title() method to capitalize each word in a string in Python:

string = "this is a test string"
capitalized_string = string.title()
print(capitalized_string)

Output:

This Is A Test String

Upvotes: 1

JonathanLoscalzo
JonathanLoscalzo

Reputation: 81

Another oneline solution could be:

" ".join(map(lambda d: d.capitalize(), word.split(' ')))

Upvotes: -1

Omar
Omar

Reputation: 403

You can try this. simple and neat.

def cap_each(string):
    list_of_words = string.split(" ")

    for word in list_of_words:
        list_of_words[list_of_words.index(word)] = word.capitalize()

    return " ".join(list_of_words)

Upvotes: 2

Augustine Jose
Augustine Jose

Reputation: 1271

The .title() method won't work in all test cases, so using .capitalize(), .replace() and .split() together is the best choice to capitalize the first letter of each word.

eg: def caps(y):

     k=y.split()
     for i in k:
        y=y.replace(i,i.capitalize())
     return y

Upvotes: 2

Nandini  Ashok Tuptewar
Nandini Ashok Tuptewar

Reputation: 324

Easiest solution for your question, it worked in my case:

import string
def solve(s):
    return string.capwords(s,' ') 
    
s=input()
res=solve(s)
print(res)

Upvotes: 0

manpikin
manpikin

Reputation: 2488

Capitalize string with non-uniform spaces

I would like to add to @Amit Gupta's point of non-uniform spaces:

From the original question, we would like to capitalize every word in the string s = 'the brown fox'. What if the string was s = 'the brown fox' with non-uniform spaces.

def solve(s):
    # If you want to maintain the spaces in the string, s = 'the brown      fox'
    # Use s.split(' ') instead of s.split().
    # s.split() returns ['the', 'brown', 'fox']
    # while s.split(' ') returns ['the', 'brown', '', '', '', '', '', 'fox']
    capitalized_word_list = [word.capitalize() for word in s.split(' ')]
    return ' '.join(capitalized_word_list)

Upvotes: -1

Amit Gupta
Amit Gupta

Reputation: 2918

Although all the answers are already satisfactory, I'll try to cover the two extra cases along with the all the previous case.

if the spaces are not uniform and you want to maintain the same

string = hello    world i  am    here.

if all the string are not starting from alphabets

string = 1 w 2 r 3g

Here you can use this:

def solve(s):
    a = s.split(' ')
    for i in range(len(a)):
        a[i]= a[i].capitalize()
    return ' '.join(a)

This will give you:

output = Hello    World I  Am    Here
output = 1 W 2 R 3g

Upvotes: 7

Fuad Fouad
Fuad Fouad

Reputation: 452

In case you want to downsize

# Assuming you are opening a new file
with open(input_file) as file:
    lines = [x for x in reader(file) if x]

# for loop to parse the file by line
for line in lines:
    name = [x.strip().lower() for x in line if x]
    print(name) # Check the result

Upvotes: -2

Wim Feijen
Wim Feijen

Reputation: 874

An empty string will raise an error if you access [1:]. Therefore I would use:

def my_uppercase(title):
    if not title:
       return ''
    return title[0].upper() + title[1:]

to uppercase the first letter only.

Upvotes: 9

chuckfinley
chuckfinley

Reputation: 2595

As Mark pointed out, you should use .title():

"MyAwesomeString".title()

However, if would like to make the first letter uppercase inside a Django template, you could use this:

{{ "MyAwesomeString"|title }}

Or using a variable:

{{ myvar|title }}

Upvotes: 6

Tejas Tank
Tejas Tank

Reputation: 1206

To capitalize words...

str = "this is string example....  wow!!!";
print "str.title() : ", str.title();

@Gary02127 comment, the below solution works with title with apostrophe

import re

def titlecase(s):
    return re.sub(r"[A-Za-z]+('[A-Za-z]+)?", lambda mo: mo.group(0)[0].upper() + mo.group(0)[1:].lower(), s)

text = "He's an engineer, isn't he? SnippetBucket.com "
print(titlecase(text))

Upvotes: 2

Chen Houwu
Chen Houwu

Reputation: 2859

The .title() method can't work well,

>>> "they're bill's friends from the UK".title()
"They'Re Bill'S Friends From The Uk"

Try string.capwords() method,

import string
string.capwords("they're bill's friends from the UK")
>>>"They're Bill's Friends From The Uk"

From the Python documentation on capwords:

Split the argument into words using str.split(), capitalize each word using str.capitalize(), and join the capitalized words using str.join(). If the optional second argument sep is absent or None, runs of whitespace characters are replaced by a single space and leading and trailing whitespace are removed, otherwise sep is used to split and join the words.

Upvotes: 285

ВелоКастръ
ВелоКастръ

Reputation: 4453

A quick function worked for Python 3

Python 3.6.9 (default, Nov  7 2019, 10:44:02) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> capitalizeFirtChar = lambda s: s[:1].upper() + s[1:]
>>> print(capitalizeFirtChar('помните своих Предковъ. Сражайся за Правду и Справедливость!'))
Помните своих Предковъ. Сражайся за Правду и Справедливость!
>>> print(capitalizeFirtChar('хай живе вільна Україна! Хай живе Любовь поміж нас.'))
Хай живе вільна Україна! Хай живе Любовь поміж нас.
>>> print(capitalizeFirtChar('faith and Labour make Dreams come true.'))
Faith and Labour make Dreams come true.

Upvotes: -1

Zahran
Zahran

Reputation: 439

If only you want the first letter:

>>> 'hello world'.capitalize()
'Hello world'

But to capitalize each word:

>>> 'hello world'.title()
'Hello World'

Upvotes: 13

Soerendip
Soerendip

Reputation: 9138

The suggested method str.title() does not work in all cases. For example:

string = "a b 3c"
string.title()
> "A B 3C"

instead of "A B 3c".

I think, it is better to do something like this:

def capitalize_words(string):
    words = string.split(" ") # just change the split(" ") method
    return ' '.join([word.capitalize() for word in words])

capitalize_words(string)
>'A B 3c'

Upvotes: 4

GaryMBloom
GaryMBloom

Reputation: 5682

Don't overlook the preservation of white space. If you want to process 'fred flinstone' and you get 'Fred Flinstone' instead of 'Fred Flinstone', you've corrupted your white space. Some of the above solutions will lose white space. Here's a solution that's good for Python 2 and 3 and preserves white space.

def propercase(s):
    return ''.join(map(''.capitalize, re.split(r'(\s+)', s)))

Upvotes: 0

Konstantin Spirin
Konstantin Spirin

Reputation: 21271

Copy-paste-ready version of @jibberia anwser:

def capitalize(line):
    return ' '.join(s[:1].upper() + s[1:] for s in line.split(' '))

Upvotes: 17

user1475777
user1475777

Reputation: 90

I really like this answer:

Copy-paste-ready version of @jibberia anwser:

def capitalize(line):
    return ' '.join([s[0].upper() + s[1:] for s in line.split(' ')])

But some of the lines that I was sending split off some blank '' characters that caused errors when trying to do s[1:]. There is probably a better way to do this, but I had to add in a if len(s)>0, as in

return ' '.join([s[0].upper() + s[1:] for s in line.split(' ') if len(s)>0])

Upvotes: -3

user3717756
user3717756

Reputation:

Why do you complicate your life with joins and for loops when the solution is simple and safe??

Just do this:

string = "the brown fox"
string[0].upper()+string[1:]

Upvotes: 18

Mark Rushakoff
Mark Rushakoff

Reputation: 258128

The .title() method of a string (either ASCII or Unicode is fine) does this:

>>> "hello world".title()
'Hello World'
>>> u"hello world".title()
u'Hello World'

However, look out for strings with embedded apostrophes, as noted in the docs.

The algorithm uses a simple language-independent definition of a word as groups of consecutive letters. The definition works in many contexts but it means that apostrophes in contractions and possessives form word boundaries, which may not be the desired result:

>>> "they're bill's friends from the UK".title()
"They'Re Bill'S Friends From The Uk"

Upvotes: 1412

jibberia
jibberia

Reputation: 420

If str.title() doesn't work for you, do the capitalization yourself.

  1. Split the string into a list of words
  2. Capitalize the first letter of each word
  3. Join the words into a single string

One-liner:

>>> ' '.join([s[0].upper() + s[1:] for s in "they're bill's friends from the UK".split(' ')])
"They're Bill's Friends From The UK"

Clear example:

input = "they're bill's friends from the UK"
words = input.split(' ')
capitalized_words = []
for word in words:
    title_case_word = word[0].upper() + word[1:]
    capitalized_words.append(title_case_word)
output = ' '.join(capitalized_words)

Upvotes: 11

Related Questions