¿Cómo poner en mayúscula la primera letra de cada palabra en una cadena (Python)?


s = 'the brown fox'

Do haz algo aquí...

s debe ser:

'The Brown Fox'

¿Cuál es la forma más fácil de hacer esto?

Author: Brad, 2009-10-11

15 answers

El .title() el método de una cadena (ASCII o Unicode está bien) hace esto:

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

Sin embargo, busque cadenas con apóstrofos incrustados, como se indica en los documentos.

El algoritmo utiliza una definición simple e independiente del lenguaje de una palabra como grupos de letras consecutivas. La definición funciona en muchos contextos, pero significa que los apóstrofes en las contracciones y los posesivos forman límites de palabras, lo que puede no ser el resultado deseado:

>>> "they're bill's friends from the UK".title()
"They'Re Bill'S Friends From The Uk"
 745
Author: Mark Rushakoff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-11 13:45:01

El .title() método no puede funcionar bien,

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

Intente string.capwords() método,

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

De los documentos de python en capwords :

Divide el argumento en palabras usando str.split (), escribe en mayúscula cada palabra usando str.mayúscula (), y unir las palabras en mayúscula usando str.unir(). Si el segundo argumento opcional sep está ausente o None, las corridas de espacios en blanco se reemplazan por un solo espacio y se eliminan los espacios en blanco iniciales y finales, de lo contrario sep se utiliza para dividir y unir las palabras.

 152
Author: Chen Houwu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-04 18:07:45

Solo porque este tipo de cosas es divertido para mí, aquí hay dos soluciones más.

Dividir en palabras, inicial-tapa cada palabra de los grupos divididos, y volver a unirse. Esto cambiará el espacio en blanco que separa las palabras en un solo espacio en blanco, sin importar lo que fuera.

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

EDITAR: No recuerdo lo que estaba pensando cuando escribí el código anterior, pero no hay necesidad de construir una lista explícita; podemos usar una expresión generadora para hacerlo de manera perezosa. Así que aquí es un mejor solución:

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

Use una expresión regular para coincidir con el comienzo de la cadena, o palabras separadoras de espacios en blanco, más un solo carácter sin espacios en blanco; use paréntesis para marcar "grupos coincidentes". Escriba una función que tome un objeto match y devuelva el grupo match de espacios en blanco sin cambios y el grupo match de caracteres que no sean espacios en blanco en mayúsculas. Luego use re.sub() para reemplazar los patrones. Este no tiene los problemas de puntuación de la primera solución, ni tampoco rehacer el espacio en blanco como mi primera solución. Este produce el mejor resultado.

import re
s = 'the brown fox'

def repl_func(m):
    """process regular expression match groups for word upper-casing problem"""
    return m.group(1) + m.group(2).upper()

s = re.sub("(^|\s)(\S)", repl_func, s)


>>> re.sub("(^|\s)(\S)", repl_func, s)
"They're Bill's Friends From The UK"

Me alegro de haber investigado esta respuesta. ¡No tenía idea de que re.sub() podría tomar una función! Puede hacer un procesamiento no trivial dentro de re.sub() para producir el resultado final!

 85
Author: steveha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-03 06:25:30

Versión lista para copiar y pegar de @jibberia anwser:

def capitalize(line):
    return ' '.join(s[:1].upper() + s[1:] for s in line.split(' '))
 13
Author: Konstantin Spirin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-12 09:23:47

¿Por qué complicas tu vida con joins y for loops cuando la solución es simple y segura??

Solo haz esto:

string = "the brown fox"
string[0].upper()+string[1:]
 11
Author: Brad Larson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-30 15:15:51

If str.title () no funciona para ti, haz la mayúscula tú mismo.

  1. Dividir la cadena en una lista de palabras
  2. Escribe en mayúscula la primera letra de cada palabra
  3. Une las palabras en una sola cadena

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"

Ejemplo claro:

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)
 10
Author: jibberia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-11 06:05:41

Aquí hay un resumen de diferentes maneras de hacerlo:

La solución más simple es dividir la oración en palabras y poner en mayúscula la primera letra y luego volver a unirla.

# 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(' ')) 

Si no desea dividir la cadena de entrada en palabras primero, y usando generadores de fantasía:

# 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)) )

O sin importar itertools

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

O puedes usar expresiones regulares, desde la respuesta de steveha

# 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)

Estos funcionarán para todos estos entradas:

""           => ""       
"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"     

Ahora, estas son algunas otras respuestas que se publicaron, y entradas para las que no funcionan como se esperaba si estamos utilizando la definición de una palabra que es el comienzo de la oración o algo después de un espacio en blanco:

  return s.title()

# Undesired outputs: 
"foO baR"    => "Foo Bar"       
"foo's bar"  => "Foo'S Bar" 
"foo's1bar"  => "Foo'S1Bar"     
"foo 1bar"   => "Foo 1Bar"      

  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"      

Usar '' para la división arreglará la segunda salida, pero capwords() aún no funcionará para la primera

  return ' '.join(w.capitalize() for w in s.split(' '))    
  # or
  import string
  return string.capwords(s, ' ')

# Undesired outputs:
"foO baR"    => "Foo Bar"      

Tenga cuidado con múltiples espacios en blanco

  return ' '.join(w[0].upper() + w[1:] for w in s.split())
# Undesired outputs:
"foo    bar" => "Foo Bar"                 
 10
Author: aljgom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-07 22:03:52

Una cadena vacía generará un error si accede a [1:], por lo tanto, usaría:

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

A mayúscula la primera letra solamente.

 5
Author: Wim Feijen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-10 16:14:35

Como Mark señaló, debe usar .title():

"MyAwesomeString".title()

Sin embargo, si desea hacer la primera letra en mayúscula dentro de una plantilla de django, podría usar esto:

{{ "MyAwesomeString"|title }}

O usando una variable:

{{ myvar|title }}
 2
Author: chuckfinley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-16 13:04:49

El método sugerido str.title () no funciona en todos los casos. Por ejemplo:

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

En Lugar de "A B 3c".

Creo que es mejor hacer algo como esto:

def capitalize_words(string):
    words = string.split()
    return ' '.join([word.capitalize() for word in words])

capitalize_words(string)
>'A B 3c'
 2
Author: Sören,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-11 17:57:17

Para poner en mayúscula las palabras...

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

@Gary02127 comentario, debajo del título del trabajo de solución con apóstrofo

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))
 2
Author: Tejas Tank,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-07 09:33:37

No pase por alto la preservación del espacio en blanco. Si desea procesar 'fred flinstone' y obtiene 'Fred Flinstone' en lugar de 'Fred Flinstone', ha dañado su espacio en blanco. Algunas de las soluciones anteriores perderán espacio en blanco. Aquí hay una solución que es buena para Python 2 y 3 y conserva el espacio en blanco.

def propercase(s):
    return ''.join(map(''.capitalize, re.split(r'(\s+)', s)))
 1
Author: Gary02127,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-30 21:08:36

Si solo quieres la primera letra: 'hola mundo'.capitalizar() Salida: Hello world

Pero para poner en mayúscula cada palabra: 'hola mundo'.titular() Salida: Hello world

 1
Author: Zahran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-04 21:11:18

* * En caso de que desee reducir el tamaño * *

 #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
 0
Author: Fouad Djebbar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-14 08:44:42

Realmente me gusta esta respuesta:

Versión lista para copiar y pegar de @jibberia anwser:

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

Pero algunas de las líneas que estaba enviando separaron algunos caracteres en blanco " que causaron errores al tratar de hacer s[1:]. Probablemente hay una mejor manera de hacer esto, pero tuve que agregar en un if len (s)>0, como en

return ' '.join([s[0].upper() + s[1:] for s in line.split(' ') if len(s)>0])
 -2
Author: user1475777,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-11 10:41:57