Skip to content

Instantly share code, notes, and snippets.

@shrkw
Last active August 29, 2015 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shrkw/2ed1a579cfeec00a2b4e to your computer and use it in GitHub Desktop.
Save shrkw/2ed1a579cfeec00a2b4e to your computer and use it in GitHub Desktop.
defaultdictを返すdefaultdictを作って、KeyErrrorの発生しない世界を作る(+JSONのパースでの利用例) ref: http://qiita.com/shrkw/items/6f872ece6b29e160c0ec
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
... d[k].append(v)
...
>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
def _factory():
return collections.defaultdict(_factory)
>>> import collections
>>> def _factory():
... return collections.defaultdict(_factory)
...
>>> d = collections.defaultdict(_factory)
>>> d['a']
defaultdict(<function _factory at 0x105e93aa0>, {})
>>> d['a']['b']
defaultdict(<function _factory at 0x105e93aa0>, {})
>>> d['a']['b'][1]
defaultdict(<function _factory at 0x105e93aa0>, {})
>>> d[1][1][0][1][1][1][1][1]
defaultdict(<function _factory at 0x105e93aa0>, {})
{
"class":{
"id":1,
"subject":"Math",
"students":[
{
"name":"Alice",
"age":30
},
{
"name":"Bob",
"age":40,
"address":{
"country":"JP"
}
},
{
"name":"Charlie",
"age":20,
"address":{
"country":"US",
"state":"MA",
"locality":"Boston"
}
}
]
}
}
In [47]: j = json.loads(s)
In [54]: for student in j["class"]["students"]:
print(student["name"])
....:
Alice
Bob
Charlie
In [55]: for student in j["class"]["students"]:
print(student["address"]["state"])
....:
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-55-69836c86e040> in <module>()
1 for student in j["class"]["students"]:
----> 2 print(student["address"]["state"])
3
KeyError: 'address'
def _hook(d):
return collections.defaultdict(_factory, d)
In [75]: j2 = json.loads(s, object_hook=_hook)
In [83]: for student in j2["class"]["students"]:
....: print(student["address"]["state"])
....:
defaultdict(<function _factory at 0x10a57ccf8>, {})
defaultdict(<function _factory at 0x10a57ccf8>, {})
MA
In [91]: def _dd(v, alt_val="default_state"):
return alt_val if isinstance(v, collections.defaultdict) and len(v) == 0 else v
....:
In [92]: for student in j2["class"]["students"]:
print(_dd(student["address"]["state"]))
....:
default_state
default_state
MA
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment