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モジュールを使います。 - 要素の抽出や変換も必要なら内包表記を使います。
変換する前に、入力形式が何を保証しているかを確認してください。外部テキストをプログラムに取り込む境界で、結果の型と必須フィールドを検証し、不正なデータを呼び出し元が処理できる形で報告しましょう。