Bir dizedeki her kelimenin ilk harfini nasıl büyük yazılır?


588
s = 'the brown fox'

... burada bir şeyler yap ...

s olmalı :

'The Brown Fox'

Bunu yapmanın en kolay yolu nedir?

Yanıtlar:


989

.title()Bir dize (ASCII veya Unicode olan para cezasıyla) yöntemi yapar:

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

Bununla birlikte, dokümanlarda belirtildiği gibi gömülü kesme işareti bulunan dizelere dikkat edin.

Algoritma, ardışık harf grupları olarak dilden basit bir dil tanımı kullanır. Tanım birçok bağlamda çalışır, ancak kasılmalardaki ve sahipliklerdeki kesme işaretlerinin, istenen sonuç olmayabilecek kelime sınırları oluşturduğu anlamına gelir:

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

56
Ben gibi bir şey ile sahiplenici sorun önlemek" ".join(w.capitalize() for w in s.split())
mehtunguh

3
bu, çoğu dize için güvenli değildir, çünkü sahip olunan her kelime bile büyük harfle yazılır.

10
String.title () ile ilgili bir sorun var. Örneğin, kullandığınızda, "e g 3b"istenen sonuç olacaktır "E G 3b". Ancak "e g 3b".title()geri döner "E G 3B".
Sören

7
Bunun da buna neden olacağını unutmayın:In [2]: 'tEst'.title() Out[2]: 'Test'
Jonas Libbrecht

4
Harika cevap ve yorumlar, python'da her şeyin ihtiyacınız olan şekilde davranmadığını, ancak bunu yapmanın her zaman uygun yolları olduğunu vurgulamaktadır. En uygun yol genellikle python-titlecase
Aaron3468 22:18

189

.title()Yöntem, iyi çalışamaz

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

string.capwords()Yöntemi deneyin ,

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

Gönderen capwords üzerine piton docs :

Bağımsız değişkeni str.split () kullanarak kelimelere ayırın, str.capitalize () kullanarak her kelimeyi büyük harfle kullanın ve str.join () kullanarak büyük harfle yazılmış kelimelere katılın. İsteğe bağlı ikinci bağımsız değişken sep yoksa veya Hiçbiri yoksa, boşluk karakterlerinin çalışması tek bir boşlukla değiştirilir ve öndeki ve sondaki boşluk kaldırılır, aksi takdirde sep sözcükleri bölmek ve birleştirmek için kullanılır.


2
Capwords hala eksik ve böyle bir şeyle başa çıkmıyor "There once was a string with an 'that had words right after it and then closed'". Bu örnekle, dışındaki tüm dünyalar thatbeklendiği gibi büyük harfle yazılır. Sonuçlar varlık"There Once Was A String With An 'that Had Words Right After It And Then Closed'"
devonbleibtrey

Yine de, bu title()normal durumlardan daha iyi çalışır . Benim durumumda, doğru şekilde title()işlenirken aksan veya dierezisli isimler için kötü bir çıktı döndürür capwords().
houcros

1
İyi, ama yine de "İngiltere / İngiltere" ayrımını
mahvediyor

@Chen Houwu, İngiltere / İngiltere mükemmel bir karşı örnektir. Python'un benzer bir yöntem kullanarak mevcut büyük harfleri küçük harflerle okumasını nasıl önleyebiliriz?
h0r53

104

Bu tür şeyler benim için eğlenceli olduğu için, işte iki çözüm daha var.

Kelimelere bölün, bölünmüş gruplardan her kelimeyi ilk harflerle yazın ve yeniden katılın. Bu, kelimeleri ne olursa olsun, kelimeleri tek bir beyaz boşluğa ayıran beyaz boşluğu değiştirir.

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

DÜZENLEME: Yukarıdaki kodu yazarken ne düşündüğümü hatırlamıyorum, ancak açık bir liste oluşturmaya gerek yok; tembel bir şekilde yapmak için bir jeneratör ifadesi kullanabiliriz. İşte daha iyi bir çözüm:

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

Dizenin başlangıcını veya sözcükleri ayıran boşlukları ve boşluk olmayan tek bir karakteri eşleştirmek için normal bir ifade kullanın; "eşleşme gruplarını" işaretlemek için parantez kullanın. Bir eşleşme nesnesini alan ve boşlukta boşluk eşleme grubunu değiştirmeden boşluk olmayan karakter eşleme grubunu büyük harf olarak döndüren bir işlev yazın. Sonra re.sub()desenleri değiştirmek için kullanın . Bu, ilk çözümün noktalama sorunlarına sahip değildir veya beyaz alanı ilk çözümüm gibi yeniden yapmaz. Bu en iyi sonucu verir.

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"

Bu cevabı araştırdığım için memnunum. re.sub()Bir fonksiyon alabileceğine dair hiçbir fikrim yoktu ! re.sub()Nihai sonucu elde etmek için içeride önemsiz işlem yapabilirsiniz !


1
Dilimler kullanarak solüsyon için +1. Kelimelerin geri kalanının büyük harf kullanımını değiştirmeden ilk harfleri büyük harfle yazacak bir şeye ihtiyacım vardı (örneğin Foo foo olur, ancak FOO fOO olur). Bu mükemmeldi.
TomNysetvold

1
büyük harf ilk karakteri büyük ve geri küçük harf döndürür
Vanuan

@Vanuan, haklısın! Doc string açıklaması bana tek yaptığı ilk harfi büyük yazmak olduğunu düşündürdü, ama aslında ne yaptığı konusunda haklısın. Cevabı düzenleyeceğim. Uyarı için teşekkür ederim.
steveha

string.capwordsChen Houwu'nun cevabındaki belgelere göre bu böyle görünüyor .
Adrian Keister

1
Yukarıdaki cevapta not edilmesi gereken bir şey, s.split () kullanmak yerine, s.split ('') kullanmak daha iyi olduğunu düşünüyorum. Bu dize bazı çift boşluk vardır ve, s.plit katılmadan üzerinde bu çift boşluk korumak isteyen örtmek (' ') Eğer boşluk korumaya yardımcı olacaktır çünkü iken s.split () olmaz
manpikin

21

İşte bunu yapmanın farklı yollarının bir özeti, tüm bu girdiler için çalışacaklar:

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

- En basit çözüm, cümleyi kelimelere ayırmak ve ilk harfi büyük yapmak ve tekrar birleştirmektir:

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

- Önce giriş dizesini kelimelere bölmek istemiyorsanız ve süslü oluşturucular kullanarak:

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

- Veya itertools'u içe aktarmadan:

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

- Veya steveha'nın cevabından düzenli ifadeler kullanabilirsiniz :

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

Şimdi, bunlar gönderilen diğer cevaplar ve cümlenin başlangıcı olan bir kelimenin tanımını veya boşluktan sonra herhangi bir şeyi kullanırsak, beklendiği gibi çalışmadığı girdilerdir:

  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"      

split için '' kullanılması ikinci çıktıyı düzeltir, ancak capwords () yine de ilk çıktı için çalışmaz

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

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

Birden çok boş alana dikkat edin

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

Kapsamlı bir özet için +1. Sadece bir rakamı takip eden bir kelimeyi büyük harfle yazmanın bir yolunu arıyorum (her kelimeyi değil). Bunu gösteren cevabınıza bir ek yapabilir misiniz? Örneğin , bir sayıyı izlediği gibi büyük harfle yazıldığı yerde lower 123 upperdönmelidir . OP'nin sorusunun kapsamının ötesine geçtiğini biliyorum, ancak zaten kapsamlı cevabınıza hoş bir eklenti. Şimdiden teşekkürler. lower 123 Upperupper
ProGrammer

Bu durumda yukarıdaki yöntemlerden bazılarını ihtiyaçlarınıza göre değiştirebilirsiniz. Ancak, cevabın bir parçası olarak eklemem, çünkü çoğu insanın aradığı şey bu değildir. Bunun için regex sürümünü kullanır ve "([0-9]+)(\s+.)"yerine "(^|\s)(\S)"(bir veya daha fazla sayı, ardından bir veya daha fazla boşluk ve sonra herhangi bir karakter eşleşir) veya "([0-9]+)(\s*.)"karakterin ardından 'sıfır veya daha fazla' boşluktan sonra büyük harf kullanmak istiyorsanız numarası
aljgom

Bu konuya baktığımdan emin olacağım, bu da başka bir özel durum hakkında düşünmemi sağladı: Yukarıdaki parçacıkları bir dize almak için nasıl değiştirirsiniz, örneğin WW1 - the great warçıktı WW1 - The Great Waryerine Ww1 .... Kısaltmalarla ilgili sorunu görüyor musunuz? Bu durumu gösteren bir şey eklemek ister misiniz? Bunu bir süredir merak ediyorum ve bunu yapmanın bir yolunu düşünemiyorum.
ProGrammer

Zaten giriş dizesinde harfle edildi harfleri değişmez yukarıda belirtilen birinci yolu, bu nedenle WW1çıktılayacaktır olarakWW1
aljgom

15

@Jibberia anwser'ın kopyala-yapıştırmaya hazır versiyonu:

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

2
Liste oluşturmaya gerek yok. str.joinjeneratörleri kabul eder.
warvariuc

@warvariuc Jeneratörlerden yararlanmak için bu kodu nasıl değiştirirdiniz?
Konstantin Spirin

1
Sadece köşeli parantezleri çıkarın, burada
warvariuc

1
@Warvariuc joingen eksplerini kabul ettiğinden bahsetmek için mükemmel olsa da , str.joinözellikle, bir liste kavrayışı kullanmak genellikle tercih edilir. Bunun nedeni join, argüman üzerinde iki kez yinelenmesidir ve bu nedenle bir jeneratör yerine kullanıma hazır bir liste sağlamak daha hızlıdır.
Bhargav Rao

1
@BhargavRao neden str.joinargüman üzerinde iki kez yinelemek gerekiyor? Az önce kontrol ettim - öyle değil. Rağmen küçük diziler için anlama listesi gerçekten daha hızlı.
warvariuc

12

Çözüm basit ve güvenli olduğunda neden hayatınızı birleştirmelerle ve döngülerle zorlaştırıyorsunuz?

Sadece bunu yap:

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

2
Çünkü birkaç kelime olabilir.
Arnaud

1
Evet, ama genellikle sadece ilk harfi büyük yazmak istiyorum. Bunu yapmanın bir yolu bu.
Deleet

1
O zaman sadece kullanmaz mıydın "the brown fox".capitalize()?
luckydonald

2
@luckydonald belki çevirmek istemiyorum 'this is John'içine 'This is john'.
janek37

Bunu basitçe yapmanın daha iyi bir yolu değil string.capitalize()(esasen yankılanan @luckydonald)
Hassan Baig

10

Str.title () işinize yaramazsa, büyük harf kullanımını kendiniz yapın.

  1. Dizeyi bir kelime listesine bölün
  2. Her kelimenin ilk harfini büyük yaz
  3. Kelimeleri tek bir dizede birleştir

Tek astarı:

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

Açık örnek:

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
Bu çözümle ilgilenilen bir nokta, herhangi bir özel boşluğu kaybetmenizdir. Bağlama bağlı olarak önemli olmayabilir.
mklauber

8

Sadece ilk harfi istiyorsan:

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

Ama her kelimeyi büyük harfle yazmak için:

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

Dikkatli çünkü 'hello New York'.capitalize()olduğunu'Hello new york'
user2314737

5

Boş bir dize [1:] erişirseniz bir Hata yükseltir, bu nedenle kullanacağım:

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

yalnızca ilk harfi büyük harfe almak için.


Bunun str.capitalizeiçin değil mi?
Eugene Pakhomov

4
@Eugene, evet ama maalesef, istenilemeyecek diğer tüm harfleri büyük harflerle yazıyor. : /
Wim Feijen

return title[:1].upper() + title[1:]boş dize dilimlemek 2 boş dize verecek şekilde bir araya
getirildiğinden

3

Mark'ın işaret ettiği gibi şunları kullanmalısınız .title():

"MyAwesomeString".title()

Ancak, bir django şablonunun içindeki ilk harfi büyük yapmak istiyorsanız, bunu kullanabilirsiniz:

{{ "MyAwesomeString"|title }}

veya bir değişken kullanarak:

{{ myvar|title }}

3

Önerilen yöntem str.title () her durumda çalışmaz. Örneğin:

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

yerine "A B 3c".

Bence, böyle bir şey yapmak daha iyidir:

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
ancak, onları ayıran boşluk sayısı 1 değilse hata oluşabilir. Referans için: hackerrank sorunu
Divakar Rajesh

3

Her ne kadar tüm cevap zaten tatmin edici olsa da, önceki 2 dava ile birlikte 2 ekstra vakayı ele almaya çalışacağım.

boşluklar aynı değilse ve aynısını korumak istiyorsanız

string = hello    world i  am    here.

tüm dize alfabe ile başlamıyorsa

string = 1 w 2 r 3g

Burada bunu kullanabilirsiniz

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

bu sana verecek

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

Umarım bu gereksiz değildir.


2
Düzgün olmayan boşlukları vurguladığınız için teşekkür ederiz. Yukarıdaki bazı cevaplar s.split ('') yerine s.split () kullanır. Düzgün olmayan alanlar için, s.split ('') kullanmanın, düzgün olmayan alanların korunmasını sağlayacağına dikkat etmek önemlidir! Tekrar teşekkürler
manpikin

Bu, düzensiz boşluklu kelimeler veya bir rakamla başlayan kelimeler için mükemmel bir şekilde çalışır. Teşekkürler :)
Amresh Giri

2

Kelimeleri büyük harfle yazmak için ...

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

@ Gary02127 yorum, kesme işareti ile çözüm çalışma başlığı altında

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

Mevcut işlevi kullan, python'da hızlı yürütme sağlar.
Tejas Tank

Kesme işareti () için çok düşkün değilim, çünkü kesme işaretlerini işlemiyor. "Söyleyemem" .title () "Söyleyemem" veriyor
Gary02127

@ Gary02127 Cevabı güncelledim, lütfen bir göz atın, sorun alanınızla da mükemmel çalıştı
Tejas Tank

1

Beyaz alanın korunmasını göz ardı etmeyin. Eğer işlemek istiyor 'fred flinstone've 'Fred Flinstone'yerine almak 'Fred Flinstone'istiyorsanız, beyaz alanınızı bozmuş olursunuz. Yukarıdaki çözümlerden bazıları beyaz alanı kaybedecektir. İşte Python 2 ve 3 için iyi ve beyaz alanı koruyan bir çözüm.

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

0

Python 3 için hızlı bir işlev çalıştı

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

Düzgün olmayan boşluklarla dizgiden büyük harf kullanımı

Bunun eski bir soru olduğunu ve muhtemelen cevapların tükenmiş olabileceğini anlıyorum, ancak @Amit Gupta'nın tek tip olmayan alanlara olan noktasını eklemek istiyorum. Orijinal sorudan, dizedeki her kelimeyi büyük harfle kullanmak istiyoruz s = 'the brown fox'. Dize s = 'the brown fox'tekdüze olmayan boşluklara sahip olsaydı .

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)

.. kodunuzu kahverengi ve tilki arasındaki boşluklar değilse sekmeleri telafi edemez ;-)
ZF007

-1

** Küçültmek istiyorsanız **

 #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

Bu yanıtı gerçekten beğendim:

@Jibberia anwser'ın kopyala-yapıştırmaya hazır versiyonu:

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

Ancak gönderdiğim satırlardan bazıları, [1:] yapmaya çalışırken hatalara neden olan boş '' karakterleri ayırdı. Muhtemelen bunu yapmanın daha iyi bir yolu var, ama ben bir len (ler)> 0,

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

2
Bu aşırı derecede karmaşık, uzunluğu kontrol etmeye ne dersiniz ?! yetersiz.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.