在Python中从其他列表/字典的嵌套字典中获取键层次结构

w8rqjzmb  于 2023-01-12  发布在  Python
关注(0)|答案(3)|浏览(137)

我有这样一个输入dict:

  1. input={'boo': 'its', 'soo': 'your', 'roo': 'choice', 'qoo': 'this', 'fizz': 'is', 'buzz': 'very', 'yoyo': 'rambling', 'wazzw': 'lorem', 'bnn': 'ipsum', 'cc': [{'boo': 'fill', 'soo': 'ing', 'roo': 'in', 'qoo': 'the', 'fizz': 'words', 'buzz': 'here', 'yoyo': 'we', 'wazzw': 'go', 'nummm': 2, 'bsdfff': 3, 'hgdjgkk': 4, 'opu': 1, 'mnb': True}, {'boo': 'again', 'soo': 'loop', 'roo': 'de', 'qoo': 'loop', 'fizz': 'wowzers', 'buzz': 'try', 'yoyo': 'again', 'wazzw': 'how', 'nummm': 1, 'bsdfff': 7, 'hgdjgkk': 0, 'opu': 1, 'mnb': True}], 'soos': ['ya'], 'tyu': 'doin', 'dddd3': 'today'}

使用python内置库如何获得每个键的层次结构(点分隔)。即:

  1. expected_output=['boo','soo','roo','qoo','fizz','buzz','yoyo','wazzw','bnn','cc','cc.boo','cc.soo','cc.roo','cc.qoo','cc.fizz','cc.buzz','cc.yoyo','cc.wazzw','cc.nummm','cc.bsdfff','cc.hgdjgkk','cc.opu','cc.mnb','soos','tyu','dddd3']

第一次尝试未处理列表:

  1. def getKeys(object, prev_key = None, keys = []):
  2. if type(object) != type({}):
  3. keys.append(prev_key)
  4. return keys
  5. new_keys = []
  6. for k, v in object.items():
  7. if prev_key != None:
  8. new_key = "{}.{}".format(prev_key, k)
  9. else:
  10. new_key = k
  11. new_keys.extend(getKeys(v, new_key, []))
  12. return new_keys
bvpmtnay

bvpmtnay1#

使用递归生成器:

  1. def hierarchy(d, prefix=None):
  2. if isinstance(d, dict):
  3. for k, v in d.items():
  4. prefix2 = f'{prefix}.{k}' if prefix else k
  5. yield prefix2
  6. if isinstance(v, list):
  7. seen = set()
  8. for x in v:
  9. if isinstance(x, dict):
  10. yield from hierarchy({k: v for k, v in x.items()
  11. if k not in seen},
  12. prefix=prefix2)
  13. seen.update(x.keys())
  14. else:
  15. yield from hierarchy(x, prefix=prefix2)
  16. elif isinstance(v, dict):
  17. yield from hierarchy(v, prefix=prefix2)
  18. out = list(hierarchy(inpt))
  19. # validation
  20. assert out == expected_output

输出:

  1. ['boo', 'soo', 'roo', 'qoo', 'fizz', 'buzz', 'yoyo', 'wazzw', 'bnn',
  2. 'cc', 'cc.boo', 'cc.soo', 'cc.roo', 'cc.qoo', 'cc.fizz', 'cc.buzz',
  3. 'cc.yoyo', 'cc.wazzw', 'cc.nummm', 'cc.bsdfff', 'cc.hgdjgkk', 'cc.opu', 'cc.mnb',
  4. 'soos', 'tyu', 'dddd3']

不同示例:

  1. list(hierarchy({'l1': {'l2': {'l3': 'test', 'l4': [['abc'], {'l5': 'def'}]}}}))
  2. # ['l1', 'l1.l2', 'l1.l2.l3', 'l1.l2.l4', 'l1.l2.l4.l5']
展开查看全部
u3r8eeie

u3r8eeie2#

莫兹韦回答的修正https://www.mycompiler.io/view/6LB7k4TVOuj

  1. # Includes $ for root node, and [] where access is through an array
  2. def hierarchy(struct, path=None):
  3. if isinstance(struct, dict):
  4. path = path if path else '$'
  5. return set(
  6. child_path
  7. for key, obj in struct.items()
  8. for child_path in hierarchy(obj, f'{path}.{key}')
  9. ).union(
  10. [path]
  11. )
  12. elif isinstance(struct, list):
  13. path = f'{path}[]' if path else '$[]'
  14. return set(
  15. child_path
  16. for obj in struct
  17. for child_path in hierarchy(obj, path)
  18. ).union(
  19. [path]
  20. )
  21. else:
  22. return [path]

或者...

  1. from itertools import chain
  2. # Excludes those $ and [] markers
  3. def hierarchy2(d):
  4. if isinstance(d, dict):
  5. return set(
  6. f'{k}.{x}' if x else k
  7. for k,v in d.items()
  8. for x in chain([''], hierarchy2(v))
  9. )
  10. elif isinstance(d, list):
  11. return set(
  12. v
  13. for l in d
  14. for v in hierarchy2(l)
  15. if v
  16. )
  17. else:
  18. return set()
展开查看全部
db2dz4w8

db2dz4w83#

要处理子列表,您可以迭代地检查每个子项是否是一个字典,如果是,则递归地将子字典的键路径追加到当前键:

  1. def get_keys(d):
  2. keys = []
  3. for key, value in d.items():
  4. if isinstance(value, list):
  5. for obj in value:
  6. if isinstance(obj, dict):
  7. for path in get_keys(obj):
  8. keys.append(f'{key}.{path}')
  9. else:
  10. keys.append(key)
  11. else:
  12. keys.append(key)
  13. return keys

因此,对于给定示例inputget_keys(input)将返回:

  1. ['boo', 'soo', 'roo', 'qoo', 'fizz', 'buzz', 'yoyo', 'wazzw', 'bnn', 'cc.boo', 'cc.soo', 'cc.roo', 'cc.qoo', 'cc.fizz', 'cc.buzz', 'cc.yoyo', 'cc.wazzw', 'cc.nummm', 'cc.bsdfff', 'cc.hgdjgkk', 'cc.opu', 'cc.mnb', 'cc.boo', 'cc.soo', 'cc.roo', 'cc.qoo', 'cc.fizz', 'cc.buzz', 'cc.yoyo', 'cc.wazzw', 'cc.nummm', 'cc.bsdfff', 'cc.hgdjgkk', 'cc.opu', 'cc.mnb', 'soos', 'tyu', 'dddd3']

演示:https://replit.com/@blhsing/OpenGoldenIntegrationtesting

展开查看全部

相关问题