1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Python 入れ子の辞書を平坦化するメソッド

Posted at

ネストされた辞書を展開して平坦にします。例えばJSONをCSVに保存する際にネスト状態を解除して平坦化したい場合に利用してください。

親キーと子キーを.で連結しています。また、子がリストの場合は親キーに1から始まる連番を付けています。

# 辞書の項目を累積的に処理する
def dict_accumulate(dct, f, acc = {}):
  for k, v in dct.items():
    acc = f(acc, k, v)
  return acc

# リストの項目を累積的に処理する
def list_accumulate(lst, f, acc = {}):
  for i, v in enumerate(lst):
    acc = f(acc, i, v)
  return acc

# 辞書に辞書をマージして返す
# ex. {'a': 1}, {'b': 2} -> {'a': 1, 'b': 2}
def update(dct, append):
  dct.update(append)
  return dct

# 入れ子の辞書を展開する
# ex. {'a': {'b': 1}} -> {'a.b': 1}
# ex. {'a': [{'b': 1}, {'b': 2}]} -> {'a1.b': 1, 'a2.b': 2}
def flatten(arg, prefix=''):
  if isinstance(arg, dict):
    return dict_accumulate(arg, lambda acc, k, v: update(acc, flatten(v, prefix + k + '.')))
  elif isinstance(arg, list):
    return list_accumulate(arg, lambda acc, i, v: update(acc, flatten(v, prefix[:-1] + str(i + 1) + '.')))
  else:
    return {prefix[:-1]: arg}
使用例
import json

str_json = '{ "users": [ { "_id": 1, "name": "Claudette Bauer", "gender": "female", "age": 36 }, { "_id": 4, "name": "Catalina Robbins", "gender": "female", "age": 29 }, { "_id": 1, "name": "Sloan Macdonald", "gender": "male", "age": 20 } ]}'
obj_json = json.loads(str_json)
flattened = flatten(obj_json)
print(flattened) # {'users1._id': 1, 'users1.name': 'Claudette Bauer', 'users1.gender': 'female', 'users1.age': 36, 'users2._id': 4, 'users2.name': 'Catalina Robbins', 'users2.gender': 'female', 'users2.age': 29, 'users3._id': 1, 'users3.name': 'Sloan Macdonald', 'users3.gender': 'male', 'users3.age': 20}
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?