---
title: Python AtCoder入門 第７講 文字列処理
tags: 
author: [佐藤](https://docswell.com/user/aomori_sato)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/PER9DD3LJ9.jpg?width=480
description: Python AtCoder入門 第７講 文字列処理 by 佐藤
published: September 19, 26
canonical: https://docswell.com/s/aomori_sato/51QE93-2026-09-19-222555
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/PER9DD3LJ9.jpg)

Python AtCoder入門
第7講 文字列処理
AtCoderの問題で扱うデータは、数値だけではありません。
文字列が主役になる問題も、A・B問題に数多く登場します。
1


# Page. 2

![Page Image](https://bcdn.docswell.com/page/P7XQ1196EX.jpg)

今回のテーマ
この講で新しく覚えることは、あまり多くありません。
第5講の、
インデックス
スライス
第6講の、
イミュータブル
内包表記
が、そのまま文字列にも通用します。
2


# Page. 3

![Page Image](https://bcdn.docswell.com/page/37K922PG7D.jpg)

この講のゴール
文字列ならではの道具を上乗せします。
インデックスとスライス
文字列のループ
split / join
replace / count
ord / chr
f-string
3


# Page. 4

![Page Image](https://bcdn.docswell.com/page/LJ3W44X5J5.jpg)

コードファイル名の方針
この講でも、コード例ごとにファイル名を付けます。
string_basic.py
count_char.py
palindrome.py
split_join.py
shift_chars.py
answer_7_1.py
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/8JDKQQ2YEG.jpg)

7-1 文字列の基本
文字列は、
1文字ずつが並んだもの
として扱えます。
リストとほとんど同じ感覚です。
5


# Page. 6

![Page Image](https://bcdn.docswell.com/page/VEPKLL1278.jpg)

インデックス
S = &quot;abcdef&quot;
print(S[0])
print(S[-1])
print(len(S))
出力：
a
f
6
インデックスは0始まりです。
6


# Page. 7

![Page Image](https://bcdn.docswell.com/page/27VVQQYX7Q.jpg)

スライス
S = &quot;abcdef&quot;
print(S[1:4])
print(S[:3])
print(S[3:])
print(S[::-1])
出力：
bcd
abc
def
fedcba
7


# Page. 8

![Page Image](https://bcdn.docswell.com/page/5JGLWW9R7L.jpg)

S[::-1]
S[::-1]
で文字列を逆順にできます。
回文判定などで非常によく使います。
第5講のリストのスライスと同じです。
8


# Page. 9

![Page Image](https://bcdn.docswell.com/page/47QY33WYEP.jpg)

文字列は変更できない
リストとは違い、文字列は中身を書き換えられません。
S = &quot;abcdef&quot;
S[0] = &quot;z&quot;
# TypeError
文字列は イミュータブル です。
9


# Page. 10

![Page Image](https://bcdn.docswell.com/page/KE4W11KZJ1.jpg)

一部を書き換えたいとき
いったんリストにして、書き換えて、文字列に戻します。
S = &quot;abcdef&quot;
A = list(S)
A[0] = &quot;z&quot;
S = &quot;&quot;.join(A)
print(S)
出力：
zbcdef
10


# Page. 11

![Page Image](https://bcdn.docswell.com/page/L71YGGXDJG.jpg)

文字列の連結
+
で連結できます。
S = &quot;abc&quot; + &quot;def&quot;
print(S)
出力：
abcdef
ただし、ループの中で += を繰り返すと遅くなることがあります。
11


# Page. 12

![Page Image](https://bcdn.docswell.com/page/G7WGKKN8E2.jpg)

文字を溜めるならjoin
parts = []
for c in S:
parts.append(c)
result = &quot;&quot;.join(parts)
文字数が多いときは、
リストに溜めてから join
するのが安全です。
12


# Page. 13

![Page Image](https://bcdn.docswell.com/page/4JZLZZ39E3.jpg)

string_basic.py
S = &quot;competitive&quot;
# Index access
print(S[0], S[-1], len(S))
# Slicing
print(S[0:6])
print(S[6:])
# Reverse
print(S[::-1])
# Convert to a list to modify
A = list(S)
A[0] = &quot;C&quot;
print(&quot;&quot;.join(A))
13


# Page. 14

![Page Image](https://bcdn.docswell.com/page/YE6WZZXDEV.jpg)

string_basic.py の出力
c e 11
compet
itive
evititepmoc
Competitive
文字列でも、インデックスとスライスが使えます。
14


# Page. 15

![Page Image](https://bcdn.docswell.com/page/GE5MWWX8E4.jpg)

7-2 文字列のループと判定
文字列は for で回すと、1文字ずつ取り出せます。
S = &quot;abc&quot;
for c in S:
print(c)
出力：
a
b
c
15


# Page. 16

![Page Image](https://bcdn.docswell.com/page/9729QQXVJR.jpg)

enumerateも使える
インデックスも必要なら、 enumerate が使えます。
for i, c in enumerate(S):
print(i, c)
リストと同じ感覚です。
16


# Page. 17

![Page Image](https://bcdn.docswell.com/page/DJY4WW8Q7M.jpg)

count_char.py
# Read a string
S = input()
# Count the letter &#039;a&#039;
count = 0
for c in S:
if c == &quot;a&quot;:
count += 1
print(count)
入力例：
banana
出力例：
3
17


# Page. 18

![Page Image](https://bcdn.docswell.com/page/V7NY99Q2E8.jpg)

カウントパターン
第4講のカウントパターンがそのまま使えます。
count = 0
for c in S:
if 条件:
count += 1
単純な数え上げなら S.count() も使えます。
18


# Page. 19

![Page Image](https://bcdn.docswell.com/page/YJ9P22DD73.jpg)

部分文字列の判定
文字列にも in が使えます。
S = &quot;banana&quot;
print(&quot;a&quot; in S)
print(&quot;nan&quot; in S)
print(&quot;ban&quot; in S)
print(&quot;nnn&quot; in S)
連続した部分文字列が含まれるかを調べます。
19


# Page. 20

![Page Image](https://bcdn.docswell.com/page/GJ8D5535JD.jpg)

in_string.py
S = &quot;banana&quot;
print(&quot;a&quot; in S)
print(&quot;nan&quot; in S)
print(&quot;ban&quot; in S)
print(&quot;nnn&quot; in S)
出力：
True
True
True
False
20


# Page. 21

![Page Image](https://bcdn.docswell.com/page/LJLMYYV3ER.jpg)

回文判定
前から読んでも後ろから読んでも同じ文字列を、
回文
と言います。
判定は簡単です。
if S == S[::-1]:
print(&quot;Yes&quot;)
else:
print(&quot;No&quot;)
21


# Page. 22

![Page Image](https://bcdn.docswell.com/page/47MYNNGM7W.jpg)

palindrome.py
# Read a string
S = input()
# A palindrome reads the same forwards and backwards
if S == S[::-1]:
print(&quot;Yes&quot;)
else:
print(&quot;No&quot;)
入力例：
level
出力例：
Yes
22


# Page. 23

![Page Image](https://bcdn.docswell.com/page/P7R9DDZLE9.jpg)

7-3 文字列メソッド
文字列には便利なメソッドがあります。
まずは、よく使うものを押さえます。
split
join
replace
count
upper
lower
23


# Page. 24

![Page Image](https://bcdn.docswell.com/page/PJXQ11167X.jpg)

split
split()
は、文字列を区切ってリストにします。
S = &quot;3 1 4&quot;
print(S.split())
S = &quot;a,b,c&quot;
print(S.split(&quot;,&quot;))
出力：
[&#039;3&#039;, &#039;1&#039;, &#039;4&#039;]
[&#039;a&#039;, &#039;b&#039;, &#039;c&#039;]
24


# Page. 25

![Page Image](https://bcdn.docswell.com/page/3JK9222GJD.jpg)

join
join()
は、リストを1つの文字列にまとめます。
A = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]
print(&quot;&quot;.join(A))
print(&quot; &quot;.join(A))
print(&quot;,&quot;.join(A))
出力：
abc
a b c
a,b,c
25


# Page. 26

![Page Image](https://bcdn.docswell.com/page/LE3W4445E5.jpg)

joinの書き方
&quot;区切り文字&quot;.join(リスト)
という形です。
「リストを連結する」ではなく、
区切り文字でリストをつなぐ
と考えると覚えやすいです。
26


# Page. 27

![Page Image](https://bcdn.docswell.com/page/8EDKQQQY7G.jpg)

joinに渡せるもの
join
に渡せるのは、文字列のリストだけです。
A = [1, 2, 3]
print(&quot; &quot;.join(A))
print(&quot; &quot;.join(map(str, A)))
# TypeError
# 1 2 3
数値は str に変換します。
27


# Page. 28

![Page Image](https://bcdn.docswell.com/page/V7PKLLL2J8.jpg)

split_join.py
# Read a line and split it into words
S = input()
words = S.split()
print(len(words))
# Join them back with a different separator
print(&quot;-&quot;.join(words))
# Reverse the order of words
print(&quot; &quot;.join(words[::-1]))
28


# Page. 29

![Page Image](https://bcdn.docswell.com/page/2JVVQQQXJQ.jpg)

split_join.py の実行例
入力例：
apple banana cherry
出力例：
3
apple-banana-cherry
cherry banana apple
3つ目は、単語の順序を逆にしています。
29


# Page. 30

![Page Image](https://bcdn.docswell.com/page/5EGLWWWRJL.jpg)

replace と count
S = &quot;banana&quot;
print(S.replace(&quot;a&quot;, &quot;o&quot;))
print(S.count(&quot;a&quot;))
print(S.count(&quot;na&quot;))
出力：
bonono
3
2
30


# Page. 31

![Page Image](https://bcdn.docswell.com/page/4JQY333Y7P.jpg)

replaceの注意
は、該当箇所をすべて置き換えます。
ただし、元の文字列は変わりません。
replace
S = &quot;banana&quot;
S.replace(&quot;a&quot;, &quot;o&quot;)
print(S)
出力：
banana
31


# Page. 32

![Page Image](https://bcdn.docswell.com/page/K74W111ZE1.jpg)

代入し直す
変更後の文字列を使いたいなら、代入し直します。
S = &quot;banana&quot;
S = S.replace(&quot;a&quot;, &quot;o&quot;)
print(S)
出力：
bonono
文字列はイミュータブルです。
32


# Page. 33

![Page Image](https://bcdn.docswell.com/page/LJ1YGGGDEG.jpg)

replace_count.py
# Read a string
S = input()
# Count occurrences
print(S.count(&quot;a&quot;))
# Replace all occurrences
T = S.replace(&quot;a&quot;, &quot;*&quot;)
print(T)
# The original string is unchanged
print(S)
33


# Page. 34

![Page Image](https://bcdn.docswell.com/page/GJWGKKK872.jpg)

replace_count.py の実行例
入力例：
banana
出力例：
3
b*n*n*
banana
34


# Page. 35

![Page Image](https://bcdn.docswell.com/page/4EZLZZZ973.jpg)

大文字小文字と判定
メソッド
S.upper()
S.lower()
S.isdigit()
S.isalpha()
意味
すべて大文字にする
すべて小文字にする
すべて数字かどうか
すべて英字かどうか
35


# Page. 36

![Page Image](https://bcdn.docswell.com/page/Y76WZZZD7V.jpg)

upper_lower.py
S = &quot;AtCoder&quot;
print(S.upper())
print(S.lower())
print(&quot;123&quot;.isdigit())
print(&quot;12a&quot;.isdigit())
出力：
ATCODER
atcoder
True
False
36


# Page. 37

![Page Image](https://bcdn.docswell.com/page/G75MWWW874.jpg)

大文字小文字を揃える
大文字小文字を区別せずに比較したいときは、
両方を lower() に揃えます。
if S.lower() == T.lower():
print(&quot;Same&quot;)
37


# Page. 38

![Page Image](https://bcdn.docswell.com/page/9J29QQQVER.jpg)

7-4 文字コードと文字の計算
文字には、それぞれ番号が割り当てられています。
ord() ：文字から番号へ
chr() ：番号から文字へ
文字を計算で扱うときに使います。
38


# Page. 39

![Page Image](https://bcdn.docswell.com/page/DEY4WWWQJM.jpg)

ord と chr
print(ord(&quot;a&quot;))
print(ord(&quot;b&quot;))
print(ord(&quot;z&quot;))
print(chr(97))
print(chr(122))
出力：
97
98
122
a
z
39


# Page. 40

![Page Image](https://bcdn.docswell.com/page/VJNY999278.jpg)

文字を0〜25に変換する
a
から z は連続した番号になっています。
c = &quot;e&quot;
print(ord(c) - ord(&quot;a&quot;))
出力：
4
a=0
, b=1 , ..., e=4 です。
40


# Page. 41

![Page Image](https://bcdn.docswell.com/page/YE9P222DJ3.jpg)

数字から文字に戻す
逆向きは、
chr(i + ord(&quot;a&quot;))
です。
print(chr(0 + ord(&quot;a&quot;)))
print(chr(25 + ord(&quot;a&quot;)))
出力：
a
z
41


# Page. 42

![Page Image](https://bcdn.docswell.com/page/GE8D5555ED.jpg)

ord_chr.py
# Character to number
for c in &quot;abz&quot;:
print(c, ord(c) - ord(&quot;a&quot;))
# Number to character
for i in [0, 1, 25]:
print(i, chr(i + ord(&quot;a&quot;)))
42


# Page. 43

![Page Image](https://bcdn.docswell.com/page/LELMYYY37R.jpg)

ord_chr.py の出力
a 0
b 1
z 25
0 a
1 b
25 z
43


# Page. 44

![Page Image](https://bcdn.docswell.com/page/4JMYNNNMJW.jpg)

文字をずらす
各文字をアルファベット順に K 個ずらす処理です。
手順：
1. ord(c) - ord(&quot;a&quot;) で0〜25にする
2. K を足す
3. % 26 で折り返す
4. chr() で文字に戻す
44


# Page. 45

![Page Image](https://bcdn.docswell.com/page/PJR9DDDL79.jpg)

% 26 が重要
の次は a に戻る必要があります。
そこで、
z
(番号 + K) % 26
とします。
第2講の「周期性を余りで扱う」の実例です。
45


# Page. 46

![Page Image](https://bcdn.docswell.com/page/PEXQ1126JX.jpg)

shift_chars.py
# Read a lowercase string and the shift amount
S = input()
K = int(input())
# Shift each character, wrapping around with % 26
parts = []
for c in S:
shifted = (ord(c) - ord(&quot;a&quot;) + K) % 26
parts.append(chr(shifted + ord(&quot;a&quot;)))
print(&quot;&quot;.join(parts))
46


# Page. 47

![Page Image](https://bcdn.docswell.com/page/3EK922MGED.jpg)

shift_chars.py の実行例
入力例：
xyz
3
出力例：
abc
x → a
, y → b , z → c と折り返しています。
47


# Page. 48

![Page Image](https://bcdn.docswell.com/page/L73W44Y575.jpg)

内包表記でも書ける
print(&quot;&quot;.join(chr((ord(c) - ord(&quot;a&quot;) + K) % 26 + ord(&quot;a&quot;)) for c in S))
短くはなります。
ただし、読みやすいかどうかは別問題です。
読めなくなる手前で止めましょう。
48


# Page. 49

![Page Image](https://bcdn.docswell.com/page/87DKQQ5YJG.jpg)

7-5 出力フォーマット
最後に、出力形式を整える方法を扱います。
AtCoderでは、答えが合っていても、
出力形式が違うとWA
になります。
49


# Page. 50

![Page Image](https://bcdn.docswell.com/page/VJPKLLG2E8.jpg)

f-string
文字列の中に変数の値を埋め込む書き方です。
name = &quot;Sato&quot;
score = 80
print(f&quot;{name} scored {score} points.&quot;)
出力：
Sato scored 80 points.
50


# Page. 51

![Page Image](https://bcdn.docswell.com/page/2EVVQQ6XEQ.jpg)

f-stringの基本
文字列の前に f を付けます。
埋め込みたい部分を { } で囲みます。
print(f&quot;{name} scored {score} points.&quot;)
str()
に変換する必要がなく、読みやすいです。
51


# Page. 52

![Page Image](https://bcdn.docswell.com/page/57GLWWNREL.jpg)

式も書ける
{ }
の中には式も書けます。
score = 80
print(f&quot;{score * 2}&quot;)
出力：
160
52


# Page. 53

![Page Image](https://bcdn.docswell.com/page/4EQY33QYJP.jpg)

ゼロ埋め
h = 9
m = 5
print(f&quot;{h:02d}:{m:02d}&quot;)
出力：
09:05
02d
は、2桁になるまで0で埋める指定です。
53


# Page. 54

![Page Image](https://bcdn.docswell.com/page/KJ4W11NZ71.jpg)

小数の桁数指定
x = 3.14159
print(f&quot;{x:.2f}&quot;)
print(f&quot;{x:.4f}&quot;)
出力：
3.14
3.1416
指定した桁で四捨五入されて表示されます。
54


# Page. 55

![Page Image](https://bcdn.docswell.com/page/LE1YGG5D7G.jpg)

format_output.py
# Read hours and minutes
H, M = map(int, input().split())
# Zero-padded time format
print(f&quot;{H:02d}:{M:02d}&quot;)
# Embed an expression
print(f&quot;Total minutes: {H * 60 + M}&quot;)
# Decimal places
ratio = (H * 60 + M) / 1440
print(f&quot;{ratio:.4f}&quot;)
55


# Page. 56

![Page Image](https://bcdn.docswell.com/page/GEWGKK58J2.jpg)

format_output.py の実行例
入力例：
9 5
出力例：
09:05
Total minutes: 545
0.3785
56


# Page. 57

![Page Image](https://bcdn.docswell.com/page/47ZLZZN9J3.jpg)

章末まとめ
文字列は、リストと同じように使える部分があります。
インデックス
スライス
len
for
逆順は、
S[::-1]
です。
57


# Page. 58

![Page Image](https://bcdn.docswell.com/page/YJ6WZZ8DJV.jpg)

章末まとめ：イミュータブル
文字列は変更できません。
一部を書き換えるなら、
A = list(S)
A[i] = &quot;x&quot;
S = &quot;&quot;.join(A)
のように、リストにしてから戻します。
58


# Page. 59

![Page Image](https://bcdn.docswell.com/page/GJ5MWW98J4.jpg)

章末まとめ：メソッド
split()
で分割
&quot;区切り&quot;.join(A)
で連結
で置換
count() で数える
upper() / lower() で大文字小文字を変える
replace などは元の文字列を変えません。
replace()
59


# Page. 60

![Page Image](https://bcdn.docswell.com/page/LE3W44YGE5.jpg)

章末まとめ：文字の計算
ord(c) - ord(&quot;a&quot;)
で a から数えた番号にできます。
chr(i + ord(&quot;a&quot;))
で番号から文字に戻せます。
文字をずらすときは % 26 で折り返します。
60


# Page. 61

![Page Image](https://bcdn.docswell.com/page/8EDKQQ5N7G.jpg)

章末まとめ：f-string
値を埋め込むなら、
f&quot;{value}&quot;
ゼロ埋めは、
f&quot;{h:02d}&quot;
小数桁数は、
f&quot;{x:.3f}&quot;
です。
61


# Page. 62

![Page Image](https://bcdn.docswell.com/page/V7PKLLGNJ8.jpg)

練習問題 7-1 母音の個数
英小文字からなる文字列 S が与えられます。
S に含まれる母音、
a i u e o
の個数を出力してください。
62


# Page. 63

![Page Image](https://bcdn.docswell.com/page/2JVVQQ6YJQ.jpg)

練習問題 7-1：入力と出力
入力：
S
入力例：
competitive
出力例：
5
63


# Page. 64

![Page Image](https://bcdn.docswell.com/page/5EGLWWNWJL.jpg)

answer_7_1.py
# Read a string
S = input()
# Count vowels
count = 0
for c in S:
if c in &quot;aiueo&quot;:
count += 1
print(count)
c in &quot;aiueo&quot;
で母音かどうかを判定しています。
64


# Page. 65

![Page Image](https://bcdn.docswell.com/page/4JQY33QQ7P.jpg)

answer_7_1_generator.py
# Read a string
S = input()
print(sum(1 for c in S if c in &quot;aiueo&quot;))
第6講のジェネレータ式を使うと、1行で数えられます。
65


# Page. 66

![Page Image](https://bcdn.docswell.com/page/K74W11NYE1.jpg)

練習問題 7-2 逆順・大文字化
英小文字からなる文字列 S が与えられます。
S を逆順にし、さらにすべて大文字にした文字列を出力してください。
66


# Page. 67

![Page Image](https://bcdn.docswell.com/page/LJ1YGG5NEG.jpg)

練習問題 7-2：入力と出力
入力例：
atcoder
出力例：
REDOCTA
スライスと upper() を使います。
67


# Page. 68

![Page Image](https://bcdn.docswell.com/page/GJWGKKWM72.jpg)

answer_7_2.py
# Read a string
S = input()
# Reverse it and convert to uppercase
print(S[::-1].upper())
S[::-1]
の結果に対して、続けて .upper() を呼んでいます。
68


# Page. 69

![Page Image](https://bcdn.docswell.com/page/4EZLZZ5M73.jpg)

練習問題 7-3 時刻の表示
0時0分からの経過時間が、分単位で N 分と与えられます。
そのときの時刻を、
HH:MM
の形式で出力してください。
69


# Page. 70

![Page Image](https://bcdn.docswell.com/page/Y76WZZ957V.jpg)

練習問題 7-3：入力と出力
入力例：
545
出力例：
09:05
と M は2桁です。
1桁の場合は先頭を0で埋めます。
H
70


# Page. 71

![Page Image](https://bcdn.docswell.com/page/G75MWWNG74.jpg)

answer_7_3.py
# Read the elapsed minutes
N = int(input())
# Split into hours and minutes
H = N // 60
M = N % 60
# Zero-padded output
print(f&quot;{H:02d}:{M:02d}&quot;)
商が時、余りが分です。
71


# Page. 72

![Page Image](https://bcdn.docswell.com/page/9J29QQ5DER.jpg)

answer_7_3_divmod.py
# Read the elapsed minutes
N = int(input())
# divmod returns the quotient and the remainder at once
H, M = divmod(N, 60)
print(f&quot;{H:02d}:{M:02d}&quot;)
divmod()
は商と余りをまとめて返します。
72


# Page. 73

![Page Image](https://bcdn.docswell.com/page/DEY4WWKMJM.jpg)

第7講まとめ
この講では、
文字列処理
を学びました。
リストで学んだインデックスやスライスは、文字列にもそのまま使えます。
73


# Page. 74

![Page Image](https://bcdn.docswell.com/page/VJNY99R378.jpg)

次回予告
次の第8講では、
2次元リストとグリッド問題
を扱います。
第6講で予告した [[0] * W] * H の罠を、実際に実験して確かめます。
74


