HOWTO · Python

Python で文字列をリストに変換する

Python で文字、単語、区切り値、解析済みリストデータを扱うときに、list()、split()、ast.literal_eval()、リスト内包表記を使い分ける方法を説明します。

このページの内容

結果の各要素に何を入れたいかに応じて方法を選びます。文字ごとに 1 要素にするには list(text)、単語や区切り文字で分けた値には text.split()、Python リテラルを表す信頼できるテキストには ast.literal_eval(text) を使います。要素の抽出や変換が必要ならリスト内包表記を使います。完全に制御できない入力には eval() を使わないでください。任意の Python コードを実行する可能性があります。

list() で文字列を文字に変換する

list() は文字列を反復し、Unicode コードポイントごとに 1 つの要素を作ります。文を単語に分割するわけではありません。たとえば、結合文字のアクセントは、見た目には文字に付いていても別のコードポイントとして扱われることがあります。

text = "Hello"
characters = list(text)
print(characters)

これは文字単位の処理に役立ちます。空白や句読点も文字として含まれるため、除去や変換が必要なら明示的に処理してください。

split() で単語や区切り値を分割する

引数なしで split() を呼び出すと、連続する空白文字を区切りとして単語に分割します。先頭と末尾の空白は無視され、連続したスペース、タブ、改行はまとめて 1 つの区切りとして扱われます。

sentence = "Convert this string to a list"
words = sentence.split()
print(words)

入力に決まった区切り文字がある場合は、それを明示的に渡します。カンマで区切られた各フィールドの前後に空白が許されるなら、分割後に各フィールドの空白を取り除きます。

text = "red, green, blue"
colors = [item.strip() for item in text.split(",")]
print(colors)

区切り文字を明示すると、空のフィールドも保持されます。たとえば "red,,blue".split(",") では、2 つのカンマの間に空文字列が含まれます。区切り文字が見つからない場合は、元の文字列が 1 つの要素として返されます。分割回数を制限するには maxsplit を使います。"red,green,blue".split(",", maxsplit=1) なら、2 つ目の要素に green,blue がまとめて入ります。

split() は CSV パーサーではありません。"red, bright",blue のように、フィールド内に引用符で囲まれた区切り文字が含まれる場合は、引用符の規則を正しく扱える Python の csv モジュールを使ってください。

リストを表すテキストを解析する

テキストが "[1, 2, 3]" のような Python リテラル構文で書かれている場合は、ast.literal_eval() で解析できます。任意の式を評価せず、リテラル値とコンテナを受け付けます。ただし、テキスト自体は構文的に正しくなければなりません。不正な入力では ValueError または SyntaxError が発生することがあります。

import ast

text = "[1, 2, 3]"
values = ast.literal_eval(text)
if isinstance(values, list):
    print(values)
else:
    print("The parsed value is not a list")

解析に成功しても、結果がリストとは限りません。たとえば "(1, 2)" はタプルを表します。リストとして使う前に解析結果の型を確認し、入力が変わり得る場合は解析エラーも処理してください。JSON テキストには json.loads() を使います。JSON と Python リテラル構文は似ていますが、同じものではありません。入力をデータとして扱い、完全に制御できないテキストに ast.literal_eval() の代わりに eval() を使わないでください。

内包表記で変換または抽出する

内包表記を使うと、条件による抽出や変換をしながら新しいリストを作れます。この例では数字の文字だけを残します。

text = "P y 3"
digits = [char for char in text if char.isdigit()]
print(digits)

残す文字を変換することもできます。たとえば [char.lower() for char in text if char.isalpha()] のように書けます。内包表記は文字列を反復して文字を対象にします。単語を対象にしたい場合は、先に split() を呼び出してから、その単語リストに内包表記を適用してください。

適切な方法を選ぶ

  • 文字ごとにリストの要素にするには list(text) を使います。
  • 空白区切りの単語には text.split()、単純で一貫した区切りのフィールドには text.split(separator) を使います。
  • Python リテラルデータとして書かれた入力に限り ast.literal_eval() を使い、結果の型を確認して、不正なテキストを適切に処理します。
  • JSON には json.loads()、引用符付き CSV フィールドには Python の csv モジュールを使います。
  • 要素の抽出や変換も必要なら内包表記を使います。

変換する前に、入力形式が何を保証しているかを確認してください。外部テキストをプログラムに取り込む境界で、結果の型と必須フィールドを検証し、不正なデータを呼び出し元が処理できる形で報告しましょう。