Pythonの文字列結合(join,+)と繰り返し(*)を解説

文字列はユーザー名やメッセージ、ログなどに欠かせない基本データ型です。

本記事では、Pythonでよく使う文字列の結合(プラス演算子の+str.join())、そして繰り返し(乗算演算子の*)を、初心者の方でも迷わないように順を追って解説します。

エラー例やパフォーマンスの違いも含め、実践的に学べます。

Pythonの文字列結合と繰り返しの基本

結合(+,join)と繰り返し(*)の違い

文字列の「結合」は複数の文字列をつなげて1つの文字列にする操作です。

主に+str.join()を使います。

一方で「繰り返し」は、同じ文字列を指定回数だけ並べる操作で、*を使います。

以下に用途と特徴を簡潔にまとめます。

手段主な用途書き方の例注意点
+少数の文字列を手早く結合"Hello, " + nameたくさんの連結には非効率、型がstrでないとTypeError
str.join()複数要素(リストやタプル)の一括結合", ".join(colors)全要素がstrである必要がある
*同じ文字列の繰り返し"=" * 30負数は空文字、極端に大きい回数はメモリに注意

使い分けの基本ルール

  • 要素があらかじめ並んでいる(リストやタプル、イテレータ)ならstr.join()を使います。
  • 少数の文字列をその場でつなぐだけなら+で十分です。
  • 同じ文字列を繰り返すなら*が最も簡単で高速です。
  • 区切りを挟みながら繰り返したいときは、join*を組み合わせるのが堅実です。

+(プラス)で文字列を結合

基本の使い方と例

+は最も直感的な結合方法です。

少数の文字列をその場でつなぐ場合に向いています。

Python
# 基本的な結合の例
first = "Hello"
second = "World"

# 単純に結合
message = first + ", " + second + "!"
print(message)

# 複数行に分けて書きたい場合は括弧で囲むと読みやすい
long_message = (
    "Python " +
    "String " +
    "Concatenation"
)
print(long_message)
実行結果
Hello, World!
Python String Concatenation

スペース・改行を足す

半角スペースや改行文字\nを文字列として足すだけです。

視認性のために、スペースは" "を明示して書くと読み間違いが減ります。

Python
name = "Alice"
lang = "Python"

# スペースを挟む
s1 = name + " " + "likes" + " " + lang
print(s1)

# 改行を挟む
s2 = "1行目" + "\n" + "2行目"
print(s2)
実行結果
Alice likes Python
1行目
2行目

TypeError対策(strとintの結合)

+で結合するとき、両辺がstrでないとTypeErrorになります。

整数を混ぜたい場合はstr()で明示的に文字列化します。

Python
# エラー例: intをstrにしないで結合しようとするとTypeError
name = "Taro"
age = 20

try:
    text = name + "は" + age + "歳です"   # ここでTypeError
    print(text)
except TypeError as e:
    print("エラー:", e)

# 解決策1: str()で文字列化
text_ok_1 = name + "は" + str(age) + "歳です"
print(text_ok_1)

# 解決策2: joinとmap(str)を使う(全部を文字列化してから結合)
text_ok_2 = "".join([name, "は", str(age), "歳です"])
print(text_ok_2)
実行結果
エラー: can only concatenate str (not "int") to str
Taroは20歳です
Taroは20歳です

str.join()で複数の文字列を結合

リストやタプルを一気に結合

str.join()は、区切り文字となる文字列に対して呼び出し、引数のシーケンス内の全要素を結合します。

大量の要素をつなぐ場合に特に有効です。

Python
# リスト内の単語を1つの文にする
words = ["Life", "is", "short"]
sentence = " ".join(words)  # " "が区切り文字
print(sentence)

# タプルでも同様
colors = ("red", "green", "blue")
csv = ",".join(colors)
print(csv)
実行結果
Life is short
red,green,blue

区切り文字(カンマ・空白・改行)

区切り文字は自由に指定できます。

改行を使えば、複数行のテキストを手早く作れます。

Python
items = ["A", "B", "C"]

print(", ".join(items))   # カンマ+空白区切り
print(" | ".join(items))  # パイプ区切り
print("\n".join(items))   # 改行区切り
実行結果
A, B, C
A | B | C
A
B
C

パフォーマンス:+より高速

多数の小さな文字列を連結する場合、+をループで繰り返すのは非効率です。

joinは内部で必要なメモリを一度に確保するため、一般に高速です。

簡単な計測例を示します(環境により数値は変わります)。

Python
# 大量連結の速度比較デモ
import time

parts = [str(i) for i in range(50000)]

# + を使う方法(悪い例): 毎回新しい文字列を作るため遅くなりやすい
t0 = time.perf_counter()
s_plus = ""
for p in parts:
    s_plus += p
t1 = time.perf_counter()

# join を使う方法(推奨)
t2 = time.perf_counter()
s_join = "".join(parts)
t3 = time.perf_counter()

print("plusの所要時間:", t1 - t0, "秒")
print("joinの所要時間:", t3 - t2, "秒")
print("結果の長さは同じか:", len(s_plus) == len(s_join))
実行結果
plusの所要時間: 0.3083496000035666 秒
joinの所要時間: 0.00026220001745969057 秒
結果の長さは同じか: True

空要素・Noneへの対応

joinは全要素がstrであることを要求します。

空文字""は結合できますが、空要素が多いと区切りだけが連続して見える場合があります。

また、Noneが混ざるとTypeErrorになります。

Python
data = ["Alice", "", "Bob", None, "Charlie"]

# そのままjoinするとTypeError(Nonetypeが混ざっているため)
try:
    print(", ".join(data))
except TypeError as e:
    print("エラー:", e)

# 対策1: Noneや空文字を除外
filtered = [x for x in data if x]  # 空文字とNoneを除外
print(", ".join(filtered))

# 対策2: すべて文字列化して結合(ただしNoneは"None"という文字になる)
as_str = map(str, data)  # 文字列化
print(", ".join(as_str))

# 対策3: Noneは空文字に、空要素はスキップなど、方針を明示
cleaned = [x if x is not None else "" for x in data]
print(", ".join([x for x in cleaned if x != ""]))
実行結果
エラー: sequence item 3: expected str instance, NoneType found
Alice, Bob, Charlie
Alice, , Bob, None, Charlie
Alice, Bob, Charlie

上の例のように、要件に応じて「空要素を残すか除外するか」「Noneをどう扱うか」を決め、前処理を行うと安全です。

*(アスタリスク)で文字列を繰り返す

基本の使い方と例

*は同じ文字列を指定回数繰り返します。

シンプルで高速に動作します。

Python
print("ha" * 3)     # "ha"を3回
print("abc" * 0)    # 0回は空文字
print("abc" * -1)   # 負数も空文字
実行結果
hahaha

上の実行結果で2行目と3行目は空行です。

0回や負数回は空文字になる点を覚えておくと、ガード条件を簡略化できます。

罫線・インデントの作成

繰り返しは装飾や整形に便利です。

罫線や字下げを直感的に表現できます。

Python
title = "メニュー"
line = "=" * 20
print(line)
print(title)
print(line)

# インデント(空白4つを3回、つまり12スペース)
indent = " " * 12
print(indent + "- スタート")
print(indent + "- オプション")
実行結果
====================
メニュー
====================
            - スタート
            - オプション

区切り付きの繰り返しはjoin

繰り返しに区切りを入れたい場合、*だけだと末尾の区切り処理が面倒です。

joinと組み合わせると綺麗に書けます。

Python
# 悪い例: 末尾のハイフンを消すための後処理が必要
naive = ("ha-" * 3).rstrip("-")
print(naive)

# 良い例: joinで区切りを間にだけ入れる
good = "-".join(["ha"] * 3)
print(good)

# 応用: 動的回数nに対しても同様
n = 5
print(", ".join(["ok"] * n))
実行結果
ha-ha-ha
ha-ha-ha
ok, ok, ok, ok, ok

負の回数や大きな回数の注意

負の回数は空文字になります。

非常に大きな回数で繰り返すと、メモリを大量に消費しプログラムが遅くなるか、場合によってはメモリエラーになります。

サイズ感を把握しておくと安全です。

Python
unit = "abc"
n1 = -10
n2 = 1_000_000  # 例: 100万回。実行環境により注意。

# 負数は空文字
print("負数の結果の長さ:", len(unit * n1))

# 大きな回数は長さが unit の長さ × 回数 になる
big = unit * n2
print("大きな繰り返しの長さ:", len(big))
print("先頭10文字:", big[:10])
実行結果
負数の結果の長さ: 0
大きな繰り返しの長さ: 3000000
先頭10文字: abcabcabca

メモリ負荷を避ける必要がある場合は、生成しながら書き出す(ストリームに出力する)か、そもそも巨大な文字列を作らない設計を検討します。

まとめ

本記事では、文字列の結合と繰り返しの基本を整理しました。

少数の結合は+で手軽に、多数の結合はstr.join()で効率的に、同じ文字列の繰り返しは*で簡潔に表現するのが基本方針です。

+str同士でしか結合できないため、数値を混ぜるときはstr()で文字列化するか、あらかじめ全要素を整形してからjoinを使うと安全です。

joinは空要素やNoneの扱いに注意し、必要に応じてフィルタや変換を行いましょう。

繰り返しでは0回や負数が空文字になる仕様、そして極端に大きな回数によるメモリ負荷を理解しておけば、堅実なコードが書けます。

場面ごとの得意分野を踏まえて使い分けることで、読みやすく高速な文字列処理が実現できます。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!