閉じる

Pythonのpartition()で区切り文字を残して3分割する方法

Pythonで「区切り文字も欠かさず取り出したい」という場面では、partitionがとても有効です。

本記事では、splitでは失われがちな区切り文字を残したまま、文字列を確実に3分割する方法と、その使い所、落とし穴までを丁寧に解説します。

初心者の方でも段階的に理解できるよう、実行例と出力を示しながら進めます。

Pythonのpartition()とは

区切り文字を残して3分割する仕組み

str.partition(sep)は、文字列の左側から最初に見つかった区切り文字(文字列)で分割し、3つの要素からなるタプルを返します。

返り値には区切り文字そのものも含まれるため、解析や再構築が簡単になります。

sepは空文字にはできません(空なら例外が発生します)。

戻り値の順序と役割

返り値は次の3要素です。

  • 先頭部分(区切りより左)
  • 区切り文字そのもの
  • 末尾部分(区切りより右)

例として、"a=b=c".partition("=")なら、最初の=で分割するため「左」「区切り」「右」は次のようになります。

要素意味具体例
先頭部分最初の区切り文字の手前“a”
区切り文字見つかった区切り文字“=”
末尾部分区切り文字の直後から末尾“b=c”

基本構文と最小の使い方

最小の使い方は、元の文字列に対してpartitionを呼び、タプルを3変数にアンパックするだけです。

区切り文字を使わない場合は「捨てる変数」として慣習的に_を使います。

Python
# 基本の使い方
s = "key=value=more"

left, sep, right = s.partition("=")
print(left, sep, right)  # 3つの値として展開

# 区切り文字を使わないなら _ に捨てる
key, _, value_and_more = s.partition("=")
print(key, value_and_more)
実行結果
key = value=more
key value=more

なお、空文字を区切りに指定するとValueErrorになります。

Python
# 空文字は不可(例外が出ます)
try:
    "abc".partition("")
except ValueError as e:
    print(type(e).__name__, e)
実行結果
ValueError empty separator

partition()の使い方と実例

key=valueをpartitionで3分割

設定ファイルや環境変数のようにkey=value形式の行を解析するには、partition("=")が直感的で頑健です。

最初の=だけで分けるため、値側に=が含まれても安全です。

Python
# .env風の行を解析する例
lines = [
    "DB_HOST=localhost",
    "PATH=/usr/bin:/bin:/usr/local/bin",
    "SECRET=abc=def=ghi",  # 値に = を含むケース
    "NO_VALUE_LINE"        # 区切りが無いケース
]

for line in lines:
    key, sep, value = line.partition("=")
    if sep:  # 見つかった場合は sep が "=" になる
        print(f"key({key}) sep({sep}) value({value})")
    else:
        print(f"区切り無し: {line}")
実行結果
key(DB_HOST) sep(=) value(localhost)
key(PATH) sep(=) value(/usr/bin:/bin:/usr/local/bin)
key(SECRET) sep(=) value(abc=def=ghi)
区切り無し: NO_VALUE_LINE

このように、値に=が複数含まれても、最初の1つでだけ分割されるため、左側のキーが取り違えられることはありません。

最初の区切りだけで分割する

partitionは常に「最初の一致」で3分割します。

splitでもmaxsplit=1を指定すれば似たことができますが、splitは区切り文字を返り値に含めません。

Python
s = "a=b=c"

# partition は区切り文字を保持する
left, sep, right = s.partition("=")
print(left, sep, right)

# split は区切り文字を捨てるが、maxsplit=1 で2要素リスト
parts = s.split("=", 1)
print(parts)  # ["a", "b=c"]
実行結果
a = b=c
['a', 'b=c']

区切り文字を保持できるかどうかが、partitionの大きな利点です。

区切りが見つからないときの挙動

partitionは区切りが見つからない場合でも例外を出さず、(元の文字列, “”, “”)を返します。

sepが空文字になることを利用して存在判定が簡単にできます。

Python
s = "hello"
left, sep, right = s.partition(",")

print(f"left={left!r}, sep={sep!r}, right={right!r}")
print("区切りが見つかったか:", bool(sep))  # sep が空文字なら False
実行結果
left='hello', sep='', right=''
区切りが見つかったか: False

splitやrpartitionとの違い

splitとの違いと使い分け

splitとの主な違いを押さえておくと選択を誤りません。

観点partitionsplit
返すものタプル(3要素固定)リスト(要素数可変)
区切り文字返り値に含まれる返り値に含まれない
分割回数最初の1回のみ指定しなければ全て、maxsplitで制御可能
区切り未検出(s, “”, “”)[s]
既定の区切り必ず指定が必要既定は空白類(特殊動作)
  • 区切り文字を保持したい、最初の1回だけ分けたい、常に3つにアンパックしたい時はpartitionが最適です。
  • 区切り文字は不要で、可変個に分割したい時はsplitが向いています。

rpartitionで末尾から3分割

末尾側(右側)から最初に見つかった区切りで3分割するのがrpartitionです。

ファイル名と拡張子、URLの最後のスラッシュなど、右側から切りたいケースで便利です。

Python
filename = "archive.tar.gz"
left, sep, right = filename.rpartition(".")
print(left, sep, right)

no_dot = "README"
l2, s2, r2 = no_dot.rpartition(".")
print(l2, s2, r2)  # 見つからない場合は ("", "", s) を返す
実行結果
archive.tar . gz
  README

1行目では最後のピリオドで分割され、拡張子gzを簡単に取り出せています。

2行目は区切りが見つからず、左と区切りが空文字、右に元文字列が入る点がpartitionと対称的です。

どちらを選ぶかの基準

  • 左から最初の区切りで分けたい → partition
  • 右から最初の区切りで分けたい → rpartition
  • 区切り文字は不要で、複数回に分けて配列として扱いたい → split(必要ならmaxsplitを指定)

実務では、ヘッダー名と値、スキームと残り、パスと拡張子のように「一度だけ・方向固定」で分けたい場面が多く、partitionrpartitionが短く明快なコードにつながります。

よくある落とし穴とベストプラクティス

先頭や末尾が区切りのときの結果

区切りが先頭や末尾にあると「空文字」が返ります。

これは正常な挙動なので、必要に応じて空文字チェックを入れます。

Python
print("=value".partition("="))   # 先頭が区切り
print("value=".partition("="))   # 末尾が区切り
print("=only=".partition("="))   # 両側に区切り
実行結果
('', '=', 'value')
('value', '=', '')
('', '=', 'only=')

空文字を許容するかどうかは要件次第です。

例えば「キーは空不可」なら、if key:で簡単に検証できます。

連続する区切り文字の扱い

partitionは「最初に一致した1回」だけを利用します。

連続する記号でも圧縮したりはしません。

区切りは1文字でも複数文字でも構いません。

Python
s1 = "a==b"
print(s1.partition("="))    # "=" で分けると最初の1つだけ
print(s1.partition("=="))   # "==" で分ければ2文字の区切りとして動作

s2 = "a|||b"
print(s2.partition("||"))   # 最初に一致する "||" が使われる
実行結果
('a', '=', '=b')
('a', '==', 'b')
('a', '||', '|b')

どの文字列が区切りかを明確に決め、入力に合わせて単一文字か複数文字かを選ぶことが重要です。

複数回の分割を行う手順

「一度で3分割」以上に段階的な解析をしたい場合、partitionrpartitionを組み合わせると読みやすくなります。

例えばURLからスキーム、ホスト、ポート、パスを抜き出す簡単な例です。

Python
url = "https://example.com:443/path/to/page?query=1"

# 1) スキームと残り
scheme, sep, rest = url.partition("://")
if not sep:
    scheme, rest = None, url  # スキーム無しURLの簡易対応
print("scheme:", scheme)

# 2) ホスト(とポート)とパス以降
host_port, sep, path_and_query = rest.partition("/")
print("host_port:", host_port)
print("path_and_query:", "/" + path_and_query if sep else "")

# 3) ホストとポートを右から分割(ポートが無いURLにも対応)
host, sep, port = host_port.rpartition(":")
if not sep:
    host, port = host_port, None

print("host:", host)
print("port:", port)
実行結果
scheme: https
host_port: example.com:443
path_and_query: /path/to/page?query=1
host: example.com
port: 443

このように、小さな確実な分割を段階的に積み上げると、例外に強く読みやすいコードになります。

多数の区切りで一括に分けたい場合はsplitが向きますが、「この地点で1回だけ確実に切りたい」という用途にはpartitionrpartitionが適しています。

まとめ

partitionは「区切り文字を保持したまま、最初の一致で3分割する」というシンプルかつ強力なメソッドです。

返り値は常に(左, 区切り, 右)の3要素で、区切りが無い時も例外を出さず(元文字列, “”, “”)となるため、条件分岐が容易です。

splitと違って区切り文字が失われないため、ログや設定の解析、文字列の再構築に向いています。

末尾側から切りたい時は対になるrpartitionを使い分けましょう。

空文字を区切りに指定できない点や、先頭・末尾が区切りのときに空文字が返る点、連続する記号の扱いなどの挙動を押さえておけば、堅牢で読みやすい文字列処理が実現できます。

この記事を書いた人
エーテリア編集部
エーテリア編集部

人気のPythonを初めて学ぶ方向けに、文法の基本から小さな自動化まで、実際に手を動かして理解できる記事を書いています。

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

URLをコピーしました!