Python
programming

No.044【Python】文字列のリスト・辞書への変換:ast.literal_eval()

python-logo-master-v3-TM-flattened.png


今回は、文字列のリスト・辞書への変換ついて書いていきます。

I'll write about "the conversion from strings to lists or dictionaries


■ 文字列の区切り文字等による分割・リスト化

 Split or making a list with such as delimiters

 空白ありのカンマで区切られた例

>>> s = "a, b, c"

>>>
>>> l = s.split(",")
>>>
>>> print(l)
['a', ' b', ' c']
>>>
>>> print(type(l))
<class 'list'>

 数字も数値型ではなく文字列となる

数値をリストにする場合:int()やfloat()とリスト内包表記を組み合わせる

>>> s = "1-2-3"

>>>
>>> l = s.split("-")
>>>
>>> print(l)
['1', '2', '3']
>>>
>>> print(type(l[0]))
<class 'str'>
>>>
>>> l = [int(c) for c in s.split("-")]
>>>
>>> print(l)
[1, 2, 3]
>>>
>>> print(type(l[0]))
<class 'int'>


■ 文字列をリストや辞書へ変換:ast.literal_eval( )

 The conversion from strings to lists or dictionaries

 astモジュールをインポート

追加のインストールは必要なし

>>> import ast

>>>
>>> s = '["a","b","c"]'
>>>
>>> l = ast.literal_eval(s)
>>>
>>> print(l)
['a', 'b', 'c']
>>>
>>> print(type(l))
<class 'list'>

 ast.literal_eval():文字列をPythonのLiteralとして評価

数値やブール値等を表現する文字列をそのまま型の値に変換する

ast.literal_eval()は以下のLiteralを変換する
文字列/バイト列/数/タプル/リスト/辞書/集合/ブール値/None

>>> s = '{"key10":10, "key20":20}'

>>>
>>> d = ast.literal_eval(s)
>>>
>>> print(d)
{'key10': 10, 'key20': 20}
>>>
>>> print(type(d))
<class 'dict'>
>>>
>>> s = '{10, 20, 30}'
>>>
>>> se = ast.literal_eval(s)
>>>
>>> print(se)
{10, 20, 30}
>>>
>>> print(type(se))
<class 'set'>


■ eval()とast.literal_eval()の違い

 Difference between eval() and ast.literal_eval()

 ◆ eval()とast.literal_eval()の違い

① eval(): リテラル、変数およびそれらの演算を含んだ式を評価
② ast.literal_eval(): リテラルのみ含む式を評価
→ eval():+による加算を評価可能 ⇄ ast.literal_eval()評価不可

>>> s = '["z", 1 + 10]'

>>>
>>> print(eval(s))
['z', 11]
>>>
>>> print(ast.literal_eval(s))
ValueError: malformed node or string: <_ast.BinOp object at 0x102ef7a20>

 ast.literal_eval():対象をリテラルのみに限定。そのため、eval()よりも安全


■ json.loads()とast.literal_eval()の違い

 Difference between json.loads() and ast.literal_eval()

>>> import json

>>>
>>> s = '{"key1": [10, 20, 20], "key2": "abcdefg"}'
>>>
>>> print(json.loads(s))
{'key1': [10, 20, 20], 'key2': 'abcdefg'

>>> import ast

>>>
>>> s = '{"key1": [10, 20, 20], "key2": "abcdefg"}'
>>>
>>> print(ast.literal_eval(s))
{'key1': [10, 20, 20], 'key2': 'abcdefg'}

 json.loads():JSON形式の文字列が対象

json仕様から外の文字列変換は不可

 ast.literal_eval():True, False, Noneの変換可能

json.loads():True, False, Noneの変換不可

>>> s = '[True, False, None]'

>>> print(json.loads(s))
Traceback (most recent call last):
File "<pyshell#86>", line 1, in <module>
print(json.loads(s))
NameError: name 'json' is not defined
>>>
>>> print(ast.literal_eval(s))
[True, False, None]

 json.loads():true, false, nullは逆で変換可能

>>> import json

>>>
>>> s = "[true, false, null]"
>>>
>>> print(json.loads(s))
[True, False, None]

 json.loads():文字列は二重引用符(ダブルクォーテーション/")で囲むことがマスト

ast.literal_eval():一重引用符(シングル/')でも三重引用符(トリプル/''')、または"""でも可能

>>> s = "{'key1': 'abcdefg', 'key2': '''vwxyz'''}"

>>>
>>> print(json.loads(s))
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
>>>
>>> print(ast.literal_eval(s))
{'key1': 'abcdefg', 'key2': 'vwxyz'}

随時に更新していきますので、
定期的な購読をよろしくお願いします。

I'll update my article at all times.

So, please subscribe my articles from now on.

本記事について、
何か要望等ありましたら、気軽にメッセージをください!

If you have some requests, please leave some messages! by You-Tarin