2017-02-25 82 views
3

較短的代碼,我在這裏解決了這個問題https://www.hackerrank.com/challenges/capitalize爲大寫功能

說明: 給你一個字符串。你的任務是利用它的每個單詞。總之,只有第一個字符是大寫的。例12abc大寫時保持12abc - 因爲這個'標題'不能像'1 w 2 r 3g'這樣的字符串正常工作。 我需要檢查數字和小寫字母的組合。這是我的代碼:

def capitalize(string): 
    result = list (string.title()) 
    for index in range (len (string)-1): 
     if string[index].isdigit() and string[index+1].islower(): 
     result[index+1] = result[index+1].lower() 
    result = ''.join([char for char in result]) 
    return (result) 

但是這段代碼太麻煩了。有人可以幫助一個更優雅pythonic決定?謝謝!

回答

5

影響的re模塊可以幫助在這裏:

titlesub = re.compile(r'\b[a-zA-Z]').sub # Precompile regex and prebind method for efficiency 
def capitalize(string): 
    return titlesub(lambda x: x.group(0).upper(), string) 

注:\b處理文字/非文字字符的邊界(字字符字母數字和下劃線),所以它會阻止12abc從大寫a,但它不會這樣做"abc(它變成"Abc)。

雖然\b很方便,但確實意味着像"won't"這樣的字符串將大寫字母"Won'T"。如果這是一個問題,更有針對性的選擇器可以用於利用當不通過非空格字符之前:

titlesub = re.compile(r'(?<!\S)[a-zA-Z]').sub 
+0

啊忘了字的界限!是的,我認爲這將適用於更多的情況! –

+0

在下面的句子中''一旦它們被創建,它們就不能被改變。',可能是那個輸出正確的'一旦它們被創建它們就不能被改變。 –

+1

@ J.Piquard:亞爾,整個問題都很棘手。對於「word」的定義,使用負面後備排除非空格字符可能會更好:'titlesub = re.compile(r'(?<!\ S)[a-zA-Z]')。sub ' – ShadowRanger

2
' '.join([x.capitalize() for x in s.split(' ')]) 
+0

注意:不會處理非空格的空格(例如製表符)。 – ShadowRanger

+0

同意。你的答案是首選。 – Crispin

+0

我試了兩種方法使用_regular expression_和_list comprehension_使用連接,他們**都得分20/20。因爲它在練習中被稱爲比 - 該字符串由字母數字字符和空格組成。 所以不需要處理像\ t'' \ n'這樣的特殊字符。 –

1

可以使用re模塊

import re 

someStr = '1 w 2 r 3ga hello world' 
re.sub(r"(?<=[0-9])[a-zA-Z]", lambda m: m.group(0).lower(), someStr.title()) 

輸出:

# 1 W 2 R 3ga Hello World 

positive look-behind(?<=[0-9])其具有數盈其中只匹配字母字符([a-zA-Z])。有了這些比賽中,我們使用.lower()方法來「撤消」的.title()

1

這裏是不使用re模塊的替代的解決方案。

def capitalize(string): 
    result = [] 
    for word in string.split(): 
     result.append(word[0].upper() + word[1:].lower()) 
    return (' '.join(result)) 
+0

如果有兩個(或更多)連續空格,結果將不相關,我們將保留所有空格。輸入'1 w 2 r 3g'的輸出是'1 W 2 R 3g',失去了兩個空格。 –

+0

Humm,對於你的樣品「1 w 2 r 3g」,我得到了與'1 W 2 R 3g'(前後10個字母)相同的字符串長度。 –

+0

你是對的。還有其他的測試用例,包括多個空格。 –