Як написати велику літеру кожного слова в рядку?


587
s = 'the brown fox'

... зробіть щось тут ...

s має бути :

'The Brown Fox'

Який найпростіший спосіб це зробити?

Відповіді:


987

.title()Метод рядки (ASCII або UNICODE штрафу) робить це:

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

Однак слідкуйте за рядками із вбудованими апострофами, як зазначено в документах.

Алгоритм використовує просте незалежне від мови визначення слова як групи послідовних літер. Визначення працює у багатьох контекстах, але це означає, що апострофи у скороченнях і володіннях утворюють межі слова, що може бути не бажаним результатом:

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

56
Я уникаю " ".join(w.capitalize() for w in s.split())
— нав'язливої

3
це не безпечно для більшості рядків, оскільки кожне слово, навіть присвійне, стає великим.

10
Виникла проблема з string.title (). Якщо ви використовуєте, наприклад, "e g 3b"бажаний результат був би "E G 3b". Однак "e g 3b".title()повертається "E G 3B".
— Сьорен

7
Майте на увазі, що це спричинить і це:In [2]: 'tEst'.title() Out[2]: 'Test'
— Йонас Ліббрехт

4
Чудова відповідь, і коментарі підкреслюють, що в python не все поводиться так, як вам потрібно, але завжди є зручні способи зробити так. Найзручнішим способом часто є імпорт спеціально створеної бібліотеки, наприклад, python-titlecase
— Aaron3468,

189

.title()Метод не може добре працювати,

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

Спробуйте string.capwords()метод,

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

Із докерів пітона на казкові слова :

Розділіть аргумент на слова, використовуючи str.split (), використовуйте великі літери, використовуючи str.capitalize (), і з'єднайте великі слова за допомогою str.join (). Якщо необов'язковий другий аргумент sep відсутній або None, пробіли символів пробілів замінюються одним пробілом, а провідні та кінцеві пробіли видаляються, інакше sep використовується для розділення та об'єднання слів.


2
Капсулів все ще бракує і не обробляє щось подібне "There once was a string with an 'that had words right after it and then closed'". У цьому прикладі всі світи, крім thatних, використовуються з великої літери, як очікувалося. Результати"There Once Was A String With An 'that Had Words Right After It And Then Closed'"
— devonbleibtrey

Все-таки це працює краще, ніж title()у звичайних ситуаціях. У моїй ситуації title()повертає невірний вихід для імен з наголосами або діерез, при capwords()цьому правильно обробляйте їх.
— houcros

Добре, але це все-таки псує відмінність "Великобританія"
— Jonath P

104

Тільки тому, що така штука для мене цікава, ось ще два рішення.

Розділіть на слова, заздалегідь замініть кожне слово з розділених груп та приєднайтеся. Це змінить пробіл, що розділяє слова, на єдиний пробіл, незалежно від того, яким він був.

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

EDIT: Я не пам'ятаю, про що я думав, коли писав вищезгаданий код, але немає необхідності створювати чіткий список; ми можемо використовувати генераторний вираз, щоб зробити це в ледачому порядку. Тож ось краще рішення:

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

Використовуйте регулярний вираз, щоб співставити початок рядка або пробіл, що розділяє слова, плюс один символ, який не пробіляє; скористайтеся дужками для позначення "групи збігів". Напишіть функцію, яка приймає об'єкт відповідності, і повертає гру збігу білого простору незмінною, а групу збігів символів - пробіл у верхньому регістрі. Потім використовуйте re.sub()для заміни візерунків. У цього немає пунктуаційних проблем першого рішення, а також не повторюється пробіл, як у мого першого рішення. Цей дає найкращий результат.

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"

Я радий, що вивчив цю відповідь. Я не мав уявлення, що re.sub()може взяти на себе функцію! Ви можете зробити нетривіальну обробку всередині, re.sub()щоб отримати кінцевий результат!


1
+1 для розчину за допомогою скибочок. Мені знадобилося щось, що дозволить писати великі літери, не змінюючи великі літери решти слів (наприклад, Foo стає foo, але FOO стає FOO). Це було ідеально.
— TomNysetvold

1
capitalize повертає перший символ з великої літери, а решта з нижнього регістру
— Вануань

@ Вануан, ти маєш рацію! Опис рядкового документа змусило мене подумати, що все, що він робив, - це написання великої літери на першому листі, але ви маєте рацію щодо того, що він насправді робить. Я відредагую відповідь. Дякую за голову.
— steveha

Це, мабуть, те, що string.capwordsробиться, згідно з документацією у відповіді Чен Хоу.
— Адріан

1
Щось зауважити у наведеній вище відповіді, а не використовувати s.split (), я думаю, що краще використовувати s.split (''). Це тому, що у випадку, що в рядку є кілька подвійних пробілів, і ви хочете зберегти ці подвійні пробіли при з'єднанні, s.plit ('') допоможе вам зберегти пробіли, а s.split () не буде
— manpikin

21

Ось підсумок різних способів зробити це, вони працюватимуть для всіх цих входів:

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

- Найпростіше рішення - розділити речення на слова і використовувати великі літери, а потім з'єднати його:

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

- Якщо ви не хочете спочатку розділити вхідний рядок на слова та за допомогою фантазійних генераторів:

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

- Або без імпорту itertools:

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

- Або ви можете використовувати регулярні вирази, з відповіді 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)

Тепер це кілька інших відповідей, які були опубліковані, і введення, для яких вони не працюють так, як очікувалося, якщо ми використовуємо визначення слова, яке є початком речення, або що-небудь після порожнього пробілу:

  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"      

використання '' для розбиття виправить другий результат, але capwords () все одно не працюватиме для першого

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

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

Будьте обережні з кількома порожніми пробілами

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

+1 для вичерпного резюме. Я шукаю спосіб лише з великої літери, яка йде за номером (не кожне слово). Чи могли б ви внести доповнення до своєї відповіді, що це демонструє? Наприклад, lower 123 upperслід повернутись lower 123 Upper, де величина з upperвеликої літери використовується відповідно до числа. Я знаю, що це виходить за рамки питання ОП, але приємне доповнення до вашої вже обширної відповіді. Заздалегідь спасибі.
— ProGrammer

У цьому випадку ви можете змінити деякі з перерахованих вище методів, щоб відповідати вашим потребам. Однак я б не додав це як частину відповіді, оскільки це не те, що шукають більшість людей. Я б використав для нього версію регулярного вираження та використовував "([0-9]+)(\s+.)"замість "(^|\s)(\S)"(збіг одного чи кількох чисел, а потім одного чи кількох пробілів та будь-якого символу після), або "([0-9]+)(\s*.)"якщо ви хочете використовувати великі літери після пробілів "нуль чи більше" після номер
— aljgom

Я обов'язково загляну в це, що змусило задуматися про ще один особливий випадок: як би ви змінили фрагменти вище, щоб взяти рядок, наприклад, WW1 - the great warі вивести WW1 - The Great Warзамість Ww1 .... Бачите проблему зі скороченнями? Чи готові ви додати щось, що демонструє цей випадок? Я вже деякий час задаюся цим питанням і не можу придумати спосіб, як це зробити.
— ProGrammer

Перші способи, зазначені вище, не змінюють літери, які вже були WW1WW1
— написані з

15

Готова для копіювання та вставки версія @jibberia anwser:

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

2
Не потрібно складати список. str.joinприймає генератори.
— warvariuc

@warvariuc, як би ти змінив цей код на використання генераторів?
— Костянтин Спірін

1
Просто зніміть квадратні дужки, як це робиться тут
— warvariuc

1
Хоча @warvariuc є ідеальним у згадуванні, що joinприймає gen exps, У конкретному випадку str.join, як правило, переважно використовувати розуміння списку. Це відбувається тому, що вона joinповторюється двічі над аргументом, а значить, швидше надати готовий список, а не генератор.
— Bhargav Rao

1
@BhargavRao, чому str.joinпотрібно було б двічі повторити аргумент? Я щойно перевірив - це не так. Хоча для невеликих послідовностей розуміння списку справді швидше.
— warvariuc

12

Чому ви ускладнюєте своє життя приєднанням і петлям, коли рішення просте і безпечне ??

Просто зробіть це:

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

2
Бо може бути кілька слів.
— Арно

1
Так, але часто мені хочеться лише з великої літери прописати першу букву. Це спосіб це зробити.
— Делете

1
Ви б не просто використали "the brown fox".capitalize()?
— luckydonald

2
@luckydonald Тому що, можливо, я не хочу перетворюватися 'this is John'на них 'This is john'.
— janek37

Чи не кращий спосіб зробити це просто string.capitalize()(по суті, відлуння @luckydonald)
— Хассан Байг

10

Якщо str.title () не працює для вас, зробіть велику літери самостійно.

  1. Розділіть рядок на список слів
  2. Пропишіть з великої літери кожне слово
  3. Об’єднайте слова в один рядок

Одноколісний:

>>> ' '.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"

Чіткий приклад:

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)

1
Одним із цікавих моментів цього рішення є те, що ви втрачаєте будь-який спеціальний пробіл. Може не важливо залежно від контексту.
— mklauber

8

Якщо ви хочете лише перший лист:

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

Але з великої літери використовувати кожне слово:

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

Обережно, тому що 'hello New York'.capitalize()є'Hello new york'
— user2314737

5

Порожня рядок призведе до помилки, якщо ви отримуєте доступ до [1:], тому я б використовував:

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

лише пропис великої літери.


Хіба це не для чого str.capitalize?
— Євген Пахомов

4
@Eugene, так, але, на жаль, використовуйте великі регістри всіх інших літер, які можуть бути не бажаними. : /
— Вім Фейєн

return title[:1].upper() + title[1:]також би піклувався про цю проблему, оскільки нарізання порожнього рядка таким чином дало б 2 порожні рядки, об'єднавшись разом, зробити порожню рядок, яка повертається
— aljgom

3

Як зазначав Марк, ви повинні використовувати .title():

"MyAwesomeString".title()

Однак, якщо ви хочете зробити пропис першої літери всередині шаблону django , ви можете скористатися цим:

{{ "MyAwesomeString"|title }}

або за допомогою змінної:

{{ myvar|title }}

3

Запропонований метод str.title () працює не у всіх випадках. Наприклад:

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

замість "A B 3c" .

Я думаю, що краще зробити щось подібне:

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'

1
однак помилка може виникнути, якщо кількість пробілів, що розділяють їх, не 1. Для довідки: проблема з
— хакерранком

3

Хоча всі відповіді вже задовільні, але я спробую висвітлити 2 додаткові справи разом із усіма попередніми справами.

якщо пробіли не є рівномірними і ви хочете підтримувати однакові

string = hello    world i  am    here.

якщо всі рядки не починаються з алфавітів

string = 1 w 2 r 3g

Тут ви можете скористатися цим

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

це дасть тобі

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

Сподіваюсь, це не зайве.


2
Дякуємо, що виділили випадок нерівномірного простору. Деякі відповіді вище використовують s.split () замість s.split (''). Важливо зазначити, що для нерівномірних просторів використання s.split ('') забезпечить збереження нерівномірних пробілів! Ще раз
— дякую

Це чудово працює для слів з нерівними пробілами або слів, що починаються з якоїсь цифри. Дякую :)
— Amresh Giri

2

Використовуючи великі літери на словах ...

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

@ Gary02127 коментар, нижче рішення роботи з апострофом

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

Використання існуючої функції дає швидке виконання в python.
— Tejas Tank

Я не дуже люблю заголовок (), оскільки він не обробляє апострофи. "Я не можу сказати" .title () дає "Я не можу сказати"
— Gary02127

@ Gary02127 У мене була оновлена ​​відповідь, будь ласка, подивіться, прекрасно працював і з вашим проблемним доменом
— Tejas Tank

1

Не забувайте про збереження білого простору. Якщо ви хочете обробити, 'fred flinstone'а ви отримаєте 'Fred Flinstone'замість цього 'Fred Flinstone', ви зіпсували пробіл. Деякі з перерахованих вище рішень втратять пробіл. Ось таке рішення, яке добре підходить для Python 2 та 3 та зберігає простір білого кольору.

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

0

Швидка функція працювала для 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.

0

Великі літери з нерівномірними пробілами

Ну, я розумію, це старе питання, і, ймовірно, відповіді, можливо, майже вичерпані, але я хотів би додати до точки зору @Amit Gupta нерівномірні простори. З початкового запитання ми хотіли б з великої літери використати кожне слово в рядку s = 'the brown fox'. Що робити, якщо рядок був s = 'the brown fox'з нерівномірними пробілами.

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)

.. ваш код не зможе компенсувати вкладки, якщо його не пробіли між коричневим та лисом ;-)
— ZF007

-1

** Якщо ви хочете зменшити розмір **

 #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

-2

Мені дуже подобається ця відповідь:

Готова для копіювання та вставки версія @jibberia anwser:

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

Але деякі рядки, які я надсилав, розбивали деякі порожні символи, що спричинили помилки при спробі зробити s [1:]. Можливо, є кращий спосіб зробити це, але мені довелося додати в, якщо len (s)> 0, як у

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

2
Це надмірно складно, якщо ви навіть хочете перевірити довжину ?! неефективна.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.