fork download
  1. WILDCARD = object()
  2.  
  3. def iter_keys(obj):
  4. try:
  5. for k,v in obj.iteritems():
  6. yield k
  7. except AttributeError:
  8. for idx, item in enumerate(obj):
  9. yield idx
  10.  
  11. def iter_matching_key_sequences(obj, keys):
  12. if not keys:
  13. yield []
  14. return
  15.  
  16. cur_key = keys[0]
  17. rest = keys[1:]
  18. if cur_key is WILDCARD:
  19. for left in iter_keys(obj):
  20. for right in iter_matching_key_sequences(obj[left], rest):
  21. yield [left] + right
  22. else:
  23. try:
  24. inner_obj = obj[cur_key]
  25. except TypeError, KeyError:
  26. return
  27. for right in iter_matching_key_sequences(obj[cur_key], rest):
  28. yield [cur_key] + right
  29.  
  30. d = {
  31. "battletag": "corvid#1376",
  32. "games": [{
  33. "overwatch": {
  34. "characters": [{
  35. "_id": "1234",
  36. }, {
  37. "_id": "5678",
  38. }]
  39. }
  40. }, {
  41. "world of warcraft": {
  42. "characters": [{
  43. "_id": "234",
  44. }]
  45. }
  46. }]
  47. }
  48.  
  49. # integer name of game integer
  50. # vvvvvvvv vvvvvvvv vvvvvvvv
  51. for seq in iter_matching_key_sequences(d, ["games", WILDCARD, WILDCARD, "characters", WILDCARD, "_id"]):
  52. print seq
Success #stdin #stdout 0.02s 9016KB
stdin
Standard input is empty
stdout
['games', 0, 'overwatch', 'characters', 0, '_id']
['games', 0, 'overwatch', 'characters', 1, '_id']
['games', 1, 'world of warcraft', 'characters', 0, '_id']