閉じる

【Python】partitionで文字列を3分割!splitとの使い分けガイド

Pythonで文字列を分割するとき、多くの方はまずsplitを思い浮かべると思います。

しかし、Pythonには「3つにきっちり分ける」ことに特化したpartitionというメソッドがあります。

この記事では、partitionの基本からsplitとの違い、実務での使い分けパターンまで、図解とサンプルコードを交えながら丁寧に解説します。

Pythonのpartitionとは

partitionで文字列を3分割する基本

Pythonのstr.partition()メソッドは、「指定した区切り文字の最初の出現位置で、文字列を3つに分割する」ための機能です。

戻り値が3要素のタプルになることが最大の特徴です。

Python
text = "user:password:extra"

# 最初の ":" で3分割する
left, sep, right = text.partition(":")

print("left :", left)
print("sep  :", sep)
print("right:", right)
実行結果
left : user
sep  : :
right: password:extra

このようにpartitionを使うと、「区切りの前」「区切りそのもの」「区切りの後ろ」を、一度にわかりやすく取り出せます。

戻り値(タプル)の構造と使いどころ

partitionは、つねに長さ3のタプルを返します。

構造は次の通りです。

  • 0番目: 区切り文字より前の部分(left)
  • 1番目: 区切り文字そのもの(sep)
  • 2番目: 区切り文字より後ろの部分(right)

このため、次のような「同時代入」がとても書きやすくなります。

Python
config_line = "timeout=30"

key, sep, value = config_line.partition("=")

print("key  :", key)
print("sep  :", sep)
print("value:", value)
実行結果
key  : timeout
sep  : =
value: 30

キーと値を一度の操作で安全に取り出せるので、設定ファイルやログの解析などで役立ちます。

また、1番目の要素が区切り文字そのものになるので、「本当に区切られたか」を簡単に判定できる点も大きなメリットです。

Python
line = "invalid_line_without_equal"

key, sep, value = line.partition("=")

if sep == "":
    print("区切り文字 '=' が見つかりませんでした")
else:
    print("key:", key, "value:", value)
実行結果
区切り文字 '=' が見つかりませんでした

rpartitionとの違いと使い分け

str.rpartition()partitionと非常によく似ていますが、「最後の」区切り文字で3分割する点が異なります。

Python
s = "a=b=c"

print("partition :", s.partition("="))
print("rpartition:", s.rpartition("="))
実行結果
partition : ('a', '=', 'b=c')
rpartition: ('a=b', '=', 'c')

使い分けとしては、次のように考えると整理しやすいです。

  • 左側の最初の区切りで分割したいとき
    partition
  • 右側の最後の区切りで分割したいとき
    rpartition

例えば、拡張子付きファイル名をパスから分けたいときには、最後の"/"で分けるなどの用途にrpartitionが向いています。

partitionの具体的な使い方

先頭の区切り文字で3分割する例

メールアドレスの"@"でユーザー名とドメインに分ける例です。

Python
email = "user@example.com"

local, at, domain = email.partition("@")

print("local :", local)
print("at    :", at)
print("domain:", domain)
実行結果
local : user
at    : @
domain: example.com

このように「先頭の1回目の出現で必ず3つに分ける」、という挙動が一貫しているため、コードの挙動が読み取りやすくなります。

区切り文字が存在しない場合の挙動

partitionは、区切り文字が見つからなくてもエラーにはなりません

代わりに、次のようなタプルを返します。

  • 0番目: 元の文字列全体
  • 1番目: 空文字""
  • 2番目: 空文字""
Python
s = "hello"

left, sep, right = s.partition(":")

print("left :", repr(left))
print("sep  :", repr(sep))
print("right:", repr(right))

if sep == "":
    print("区切り文字は見つかりませんでした")
実行結果
left : 'hello'
sep  : ''
right: ''
区切り文字は見つかりませんでした

この挙動により、例外処理をせずに「区切りがあるかどうか」を判定できるという利点があります。

先頭・末尾の空文字に注意するケース

区切り文字が文字列の先頭や末尾にある場合、次のように空文字が含まれます。

Python
print("':value'     :", ":value".partition(":"))
print("'key:'       :", "key:".partition(":"))
print("':'          :", ":".partition(":"))
print("'::value'    :", "::value".partition(":"))
実行結果
':value'     : ('', ':', 'value')
'key:'       : ('key', ':', '')
':'          : ('', ':', '')
'::value'    : ('', ':', ':value')

このように、先頭や末尾に区切り文字があると左または右が空文字になるため、その後の処理で「最低1文字はあるはず」と決め打ちしてしまうとバグにつながります。

必要であれば、leftrightが空文字でないかをチェックしてから処理を進めると安全です。

splitとの違いと使い分け

partitionとsplitの仕様の違い

まず、partitionsplitの違いを表に整理します。

観点partitionsplit
戻り値の型タプル(tuple)リスト(list)
要素数常に3要素1〜複数(可変)
区切る位置最初(または最後:rpartition)の1か所のみ該当するすべて、または最大maxsplit
見つからないとき(元文字列, “”, “”) を返す元文字列のみのリスト[s]]
区切り文字を含めるかタプルの2番目要素として返す通常は結果に含まれない

例えば、同じ文字列に対して両者を使うと次のようになります。

Python
s = "a=b=c"

print("partition:", s.partition("="))
print("split    :", s.split("="))
実行結果
partition: ('a', '=', 'b=c')
split    : ['a', 'b', 'c']

partitionは「1回だけ3つに」、splitは「必要なだけ何個でも」というイメージを持つと理解しやすいです。

要素数が決まっているときはpartition

"key=value"のように、「区切りが1つだけ存在する前提」のデータではpartitionが非常に扱いやすいです。

Python
line = "timeout=30"

# partition 版
key, sep, value = line.partition("=")

if sep == "":
    print("不正な行です:", line)
else:
    print("key:", key, "value:", value)

# split 版 (同じことをsplitでやると…)
parts = line.split("=")

if len(parts) != 2:
    print("不正な行です:", line)
else:
    key2, value2 = parts
    print("key2:", key2, "value2:", value2)
実行結果
key: timeout value: 30
key2: timeout value2: 30

どちらも同じ結果になりますが、partitionの方が要素数チェックがシンプルで、コードの意図も明確になります。

可変長の分割が必要なときはsplit

一方で、区切りの数が変わる可能性がある場合はsplitを使うべきです。

Python
csv_line = "apple,banana,orange,grape"

fields = csv_line.split(",")

print(fields)
print("列数:", len(fields))
実行結果
['apple', 'banana', 'orange', 'grape']
列数: 4

このようなケースでpartitionを使うと、right部分にカンマつきで残ってしまうため、さらに処理が必要になり非効率です。

「1回だけ切るならpartition、何回も切るならsplit」と覚えると実務で迷いにくくなります。

パフォーマンスとコードの可読性の観点

通常の規模の処理であれば、partitionとsplitのパフォーマンス差はほとんど気にしなくて構いません

どちらもCで実装されており高速です。

ただし、コードの可読性の観点では次のような違いがあります。

  • partition
    • 「ここで1回だけ分けたい」という意図が明確
    • 戻り値が3つで固定のため型や要素数がわかりやすい
  • split
    • 可変長のデータに柔軟に対応できる
    • 要素数のチェックやアンパックがやや煩雑になる場合がある

そのため、「読みやすいコードを書きたい」「バグを減らしたい」という観点では、要素数が3つでよい場面では積極的にpartitionを選ぶのがおすすめです。

実践テクニックとパターン別ガイド

1行からキーと値をpartitionで取得

設定ファイルや環境変数など、「key=value」形式の行を処理するケースは非常に多いです。

このような場合、partitionはほぼ定番のテクニックとして使えます。

Python
lines = [
    "host=example.com",
    "timeout=30",
    "debug=true",
    "invalid_line_without_equal"
]

config = {}

for line in lines:
    # 行頭・行末の空白を除去
    line = line.strip()
    if not line:
        continue  # 空行はスキップ

    key, sep, value = line.partition("=")

    if sep == "":
        # 不正な行としてログなどに出す
        print("無視します(フォーマット不正):", line)
        continue

    config[key] = value

print("設定:", config)
実行結果
無視します(フォーマット不正): invalid_line_without_equal
設定: {'host': 'example.com', 'timeout': '30', 'debug': 'true'}

partitionを使うことで、エラー処理と通常処理が明確に分かれ、読みやすいコードになります。

ファイルパスやURLをpartitionで分解

ファイルパスやURLなど、構造がある文字列を扱う際にもpartitionは便利です。

URLからスキームと残りを分ける

Python
url = "https://example.com/path/to/resource"

scheme, sep, rest = url.partition("://")

print("scheme:", scheme)
print("sep   :", sep)
print("rest :", rest)
実行結果
scheme: https
sep   : ://
rest : example.com/path/to/resource

スキーム部分(http, https など)だけ知りたい場合、このように1行で簡単に取り出せます。

ファイルパスからディレクトリとファイル名を分ける(rpartition)

ファイルパスでは、最後の"/"でディレクトリとファイル名を分けたいケースが多いため、rpartitionを使うと便利です。

Python
path = "/home/user/projects/app/main.py"

dir_path, sep, filename = path.rpartition("/")

print("dir_path:", dir_path)
print("sep     :", sep)
print("filename:", filename)
実行結果
dir_path: /home/user/projects/app
sep     : /
filename: main.py

もちろん、実務ではos.pathpathlibといった専用モジュールを使うことも多いですが、軽量なスクリプトやちょっとした文字列処理ではpartition/rpartitionだけで十分なこともあります。

エラー文やログ文から必要な部分だけ抽出

ログファイルの1行から、ログレベルやメッセージ部分を切り出す例を考えます。

Python
logs = [
    "[INFO]  Application started",
    "[WARNING] Low disk space",
    "[ERROR] Failed to connect to database",
]

for line in logs:
    # 右側から "] " で1回だけ分割
    level_part, sep, message = line.partition("] ")

    if sep == "":
        print("フォーマット不明:", line)
        continue

    # 左側 "[INFO" から "[", "]" を除いてレベルだけにする
    level = level_part.strip("[] ")
    print(f"level={level:<7} message={message}")
実行結果
level=INFO    message=Application started
level=WARNING message=Low disk space
level=ERROR   message=Failed to connect to database

このように、ログの形式が一定で、区切り文字が1つに決まっている場合は、partitionを使うことでとても見通しの良いコードになります。

正規表現(re)と組み合わせたsplitとの比較

複雑なパターンで文字列を分割したい場合、re.splitなどの正規表現を使うこともあります。

しかし、まずはpartitionで済むかを検討することをおすすめします。

単純なパターンであれば、その方が読みやすく高速です。

正規表現splitが必要なケースの例

例えば、空白が1個以上空いている位置で分割したい場合、partitionでは対応できません。

Python
import re

line = "2025-01-01   ERROR    Something bad happened"

date, level, message = re.split(r"\s+", line, maxsplit=2)

print("date   :", date)
print("level  :", level)
print("message:", message)
実行結果
date   : 2025-01-01
level  : ERROR
message: Something bad happened

このように、区切りのパターンが「1文字」では表現しづらい場合にはre.splitが有効です。

partitionで代替できるなら積極的に使う

一方で、「最初の = で3つに分ける」「最後の / で3つに分ける」といった用途では、正規表現を使うよりpartitionの方が簡潔で明確です。

Python
s = "user:password:extra"

# 正規表現で最初の ":" だけで分ける例(あまりおすすめしない)
import re
left, right = re.split(":", s, maxsplit=1)
print("re.split:", left, right)

# partition の方が意図も明確で安全
left2, sep2, right2 = s.partition(":")
print("partition:", left2, sep2, right2)
実行結果
re.split: user password:extra
partition: user : password:extra

正規表現は強力ですが、そのぶん読み手の負担も大きくなります

「1文字の区切りで1回だけ分ける」という要件であれば、まずpartitionを使い、どうしても足りない場合にのみre.splitを検討する、という順番がおすすめです。

まとめ

partitionは「文字列を3分割する」ことに特化した、シンプルで強力なメソッドです。

区切り文字の前後と区切りそのものを一度に扱えるため、キーと値の取得、URLやパスの分解、ログやエラー文の解析などで、わかりやすく安全なコードを書けます。

要素数が決まっているときはpartition(あるいはrpartition)、可変長の分割が必要なときはsplitやre.splitというように役割を整理しておくと、実務で迷わずに最適な手段を選べるようになります。

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

URLをコピーしました!