文字列を扱う — インデックス、スライス、f-string
文字列の一部を取り出し、きれいにし、変換し、f-stringで読みやすいメッセージを組み立てます。あわせて、文字列はその場で変更できないというルールも学びます。
どうやって学びますか?
解決する問題
フォームから次の名前が届きました: " Rafi Ahmed "。前後に余分な空白があり、必要なのはファーストネーム(名)だけです。さらに、"Welcome, Rafi!"のようなメッセージも作る必要があります。
テキストをきれいにする、一部を取り出す、その一部から新しいものを組み立てる。この作業は、プログラミングで最もよく行うことの一つです。ユーザー名、メールアドレス、ID、ファイル名、住所、APIが返すものは何であれ、すべて文字列です。
そして、今日もう一つはっきりさせておきたいことがあります。知らないと何時間も失うことになる内容です。Pythonでは、文字列は変更できません。name.upper()と書いても、nameが大文字になるわけではありません。なぜそうなるのか、代わりに何をすればよいのかが、この章で最も価値のある部分です。
この章を終える頃には
- インデックスを使って、前からでも後ろからでも任意の文字を取り出せる
- スライスで一部分を切り出せる
strip、upper、lower、replace、splitを使って文字列をきれいにし、変換できる- メソッドの結果を保存しなければならない理由を説明できる
- f-stringで読みやすいメッセージを組み立てられる
前提条件: 算術 — 割り算、余り、そして小数の落とし穴.
引用符 — シングルでもダブルでも
Pythonにとって'Rafi'と"Rafi"は同じものです。2種類あるのは、文字列の中に引用符を入れても問題が起きないようにするためです:
print("It's working")
print('She said "yes"')It's working
She said "yes"3つの引用符を使うと、複数行にまたがる文字列を書けます:
note = """Dear customer,
Your order is confirmed.
Thank you."""
print(note)Dear customer,
Your order is confirmed.
Thank you.また、\nで改行、\tでタブを入れられます:
print("Name:\tRafi\nRole:\tLearner")Name: Rafi
Role: Learner長さとインデックス
word = "PYTHON"
print(len(word))
print(word[0])
print(word[1])
print(word[-1])
print(word[-2])6
P
Y
N
O頭に入れておいてほしいことが2つあります:
数えは0から始まります。 最初の文字のインデックスは0、2番目は1です。6文字の単語では、最後のインデックスは6ではなく5になります。word[6]を指定するとIndexErrorになります。この「1つ多い」ミスはとてもよくあるので、専用の名前があります。off-by-one error(オフ・バイ・ワン・エラー)です。
負のインデックスは後ろから数えます。 word[-1]は最後の文字、word[-2]はその1つ前の文字です。文字列の長さを知らなくても末尾に行ける、簡単な方法です。
スライス — 一部分を切り出す
word = "PROGRAMMING"
print(word[0:7])
print(word[7:11])
print(word[:7])
print(word[7:])
print(word[-4:])PROGRAM
MING
PROGRAM
MING
MINGword[a:b]は、aから始まり、bの手前まで(bは含まない)を意味します。終わりのインデックスは含まれません。
最初は少し不自然に感じるかもしれませんが、これには利点があります。word[0:7]とword[7:11]は、文字が重複することも抜けることもなく、ぴったりつながります。最初の数字を省くと「先頭から」、2番目の数字を省くと「末尾まで」を意味します。
文字列は変更できない
この章で最も重要なルールです:
name = "rafi"
name[0] = "R"Traceback (most recent call last):
File "D:\python-lab\lesson-06\demo.py", line 2, in <module>
name[0] = "R"
~~~~^^^
TypeError: 'str' object does not support item assignment最初のFileの行には、あなたのファイルのフルパスが表示されるので、お使いのパソコンでは見た目が違うはずです。本当に大事なのは最後の行です。既存の文字列の中の1文字を入れ替えることはできない、と言っています。では、大文字にしたり空白を取り除いたりするメソッドは、どうやって動いているのでしょうか。答えは、Pythonは元の文字列を変更せず、新しい文字列を作って返すからです。
name = " rafi "
print(name.strip())
print(name.strip().upper())
print("After all that, name is still:", name)rafi
RAFI
After all that, name is still: rafinameはまったく変わっていません。strip()は新しいきれいな文字列を作りましたが、ここではそれを表示しただけで、保存はしていません。
だから、結果を保存する必要があります:
name = " rafi "
clean_name = name.strip().upper()
print(clean_name)RAFIまたは、同じ名前に代入し直します — name = name.strip()。メソッドを呼び出して結果を捨ててしまう、このミスは誰でも最初のうちに経験します。しかもエラーは出ないので、気づくまでに時間がかかります。
便利なメソッド
raw = " Rafi Ahmed "
print(raw.strip())
print(raw.strip().lower())
print(raw.strip().upper())
print(raw.strip().replace(" ", "_"))
print(len(raw), len(raw.strip()))
print("rafi" in raw.lower())Rafi Ahmed
rafi ahmed
RAFI AHMED
Rafi_Ahmed
14 10
Truestrip()— 先頭と末尾の空白を取り除きます(途中の空白は除きません)lower()/upper()— 大文字・小文字を変換しますreplace(a, b)—aが出てくる場所すべてをbに置き換えますin— ある文字列が別の文字列の中に含まれているかを調べます
split()は文字列をいくつかの部分に分けます:
full_name = "Rafi Ahmed Khan"
parts = full_name.split(" ")
print(parts)
print(parts[0])
print(len(parts))['Rafi', 'Ahmed', 'Khan']
Rafi
3角かっこで囲まれたものはリストです。リストについては、このコースの後の章で詳しく扱います。今は、split()がそのような形で部分を返すこと、そしてインデックスを使うと1つの部分を取り出せることだけ知っておいてください。
比較する前に整えましょう。 ユーザーが"Rafi "と入力したとき、それは"rafi"とは等しくありません。末尾の空白と大文字という2つの違いがあるからです。だから実際のプロジェクトでは、比較する前に.strip().lower()を実行するのが、ほぼ当たり前の習慣になっています。
f-string — メッセージを組み立てる簡単な方法
ここまで、文字列と数値を混ぜるのは面倒でした。f-stringを使うと簡単になります。引用符の前にfを付け、波かっこ{}の中には好きな式を入れられます:
name = "Rafi"
items = 3
price = 12.5
print(f"Hello, {name}!")
print(f"{items} items cost {items * price}")
print(f"Rounded: {items * price:.2f}")Hello, Rafi!
3 items cost 37.5
Rounded: 37.50メリットは3つあります。波かっこの中で計算できること(items * price)、型のことを気にしなくてよいこと(数値は自動的に文字列になります)、そして:.2fで小数点以下の桁数を固定できることです。金額を表示するときには、これが必ず必要になります。
fを付け忘れるとどうなるか、見てみましょう:
name = "Rafi"
print("Hello, {name}")Hello, {name}エラーは出ません。ただ間違ったメッセージが表示されるだけです。一度見ておけば、後で気づきやすくなります。
完成例
account.py:
# Turn a raw form entry into a clean display name and a login id
raw_input_name = " Rafi Ahmed "
domain = "example.com"
clean = raw_input_name.strip()
parts = clean.split(" ")
first_name = parts[0]
last_name = parts[-1]
login_id = f"{first_name.lower()}.{last_name.lower()}"
email = f"{login_id}@{domain}"
initials = f"{first_name[0]}{last_name[0]}"
print(f"Display name : {clean}")
print(f"Login id : {login_id}")
print(f"Email : {email}")
print(f"Initials : {initials}")
print(f"Name length : {len(clean)} characters")Display name : Rafi Ahmed
Login id : rafi.ahmed
Email : [email protected]
Initials : RA
Name length : 10 charactersなぜparts[-1]なのでしょうか。名前は3つの部分からなることもあるからです。後ろから最後の部分を取ると、部分が2つでも3つでも正しく動きます。
うまくいかないとき
IndexError: string index out of range 指定したインデックスが文字列の末尾を超えています。len(word)が6なら、有効なインデックスは0から5までだと覚えておきましょう。最後の文字を指定するには、word[-1]と書くのが最も安全です。
TypeError: 'str' object does not support item assignment 文字列の中の1文字を変更しようとしました。これはできません。代わりに新しい文字列を作ってください。例: word = "R" + word[1:]。
メソッドを呼んだのに、何も変わらない 結果がどこにも保存されていません。name.strip()はnameを変えません。name = name.strip()と書く必要があります。
strip()で途中の空白が消えない strip()は両端でしか働きません。途中の空白を消すにはreplace(" ", "")を使います。
f-stringのメッセージがおかしい 引用符の直前にあるfを確認してください。fがないと、波かっこはふつうの文字としてそのまま表示されます。
NameError — f-stringの中の名前が分からない 波かっこの中に書いたものが作られていないか、スペルが間違っています。
ステップ 4 / 6 — 予想する
理解度をチェック
この4行は何をprintしますか?
word = "PYTHON"
print(word[0])
print(word[-1])
print(word[1:4])- AP N YTH
- BY N YTHO
- CP O YTH
- DP N YTHO
出力はHello, RAFI!になるはずでしたが、名前は小文字のままで、空白も残っています。なぜですか?
name = " rafi "
name.strip()
name.upper()
print(f"Hello, {name}!")- A1つの文字列に対してメソッドを呼べるのは1回だけで、2回は呼べない
- Bf-stringではメソッドの結果を表示できない
- C`strip()`と`upper()`は元の値を変更しません — 新しい文字列を返すので、結果を`name`に代入し直す必要があります
- D`strip()`は`upper()`より前には呼べないので、順番を逆にする必要がある
このf-stringは何がprintされますか?
item = "pen"
qty = 3
price = 12.5
print(f"{qty} x {item} = {qty * price:.2f}")- A3 x pen = 37.50
- B3 x pen = 37.5
- C{qty} x {item} = {qty * price}
- D3 x pen = 3 * 12.5
回答にはアカウントが必要です
ログインして答えを確認
問題は上にあります。頭の中で答えを考えることがいちばん大切です。ログインすると、正解・解説・3 段階のヒントを確認できます。
やってみよう
タイトルをWebアドレスに使える形に変換するslug.pyという名前のファイルを書いてください。
最初の値: title = " Learn Python Step By Step "
出力は次のようになります:
Title : Learn Python Step By Step
Slug : learn-python-step-by-step
Slug length: 25条件は4つです:
- 前後の余分な空白を取り除く
- すべてを小文字にする
- 途中の空白をダッシュに置き換える
- 3行すべてをf-stringで表示する
最後に、もう1つだけ試してください。titleを" Python for Beginners "に変えて実行します。コードに触れなくても正しい結果が出れば、答えを手で入力したのではなく、本当の計算を書けたということです。
このミッションにはまだ続きがあります
上で読んだ内容がミッションのすべてで、削られた部分はありません。Pro では次の内容が追加されます:
- 内部で実際に何が起きているか — Python がこれをどう実行するのか
- 演習の完全な解答と、ステップごとの解説
- さらに難しい追加演習
- このテーマでよく聞かれる面接の質問と模範解答