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

![python-logo-master-v3-TM-flattened.png](https://qiita-image-store.s3.amazonaws.com/0/336067/8fb9f6aa-57f7-dc4b-b4bf-a648969d315c.png)

####今回は、文字列のリスト・辞書への変換ついて書いていきます。
I'll write about "the conversion from strings to lists or dictionaries


###■ 文字列の区切り文字等による分割・リスト化
&emsp;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( )
&emsp;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()の違い
&emsp;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()の違い
&emsp;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'}
``` 


随時に更新していきますので、<br>定期的な購読をよろしくお願いします。
I'll update my article at all times.
So, please subscribe my articles from now on.

本記事について、<br>何か要望等ありましたら、気軽にメッセージをください！
If you have some requests, please leave some messages! by You-Tarin