【问题标题】:Get data from a nested dict python and data type is also mixed从嵌套的dict python中获取数据并且数据类型也是混合的
【发布时间】:2021-09-25 15:02:17
【问题描述】:

Json 数据如下所示,我必须获取给定数据中的坐标并将其列表打印为:

解:[[2, 3], [4, 1], [8, 4], [3, 2]]

data = '{"foo": {"type": "geo", "coords": [2, 3], "children": [{"type": "geo", "coords": [4 , 1], "children": [{"type": "bar", "children": [{"type": "geo", "coords": [8, 4]}]}, {"type": "geo", "coords": [3, 2]}]}]}}'

我想出了一个解决方案,但它有索引。无论dict的结构是什么,我都想要一些适用于每种情况的通用解决方案。可能吗?我是的,然后如何?

我的解决方案是:

def fun(data):
    coords_list = list()
    data = json.loads(data)
    for k in data:
        if data[k].get('coords') is not None:
            coords_list.append(data[k]['coords'])
        if data[k].get('children') is not None:
            if isinstance(data[k].get('children'), list):
                coords = data[k].get('children')[0].get('coords')
                coords_list.append(coords)
                if isinstance(data[k].get('children')[0].get('children'), list):
                    coords = data[k].get('children')[0].get('children')[0].get('children')[0].get('coords')
                    coords_list.append(coords)
                    coords = data[k].get('children')[0].get('children')[1].get('coords')
                    coords_list.append(coords)
    return coords_list

【问题讨论】:

  • 你的意思是“在每种情况下都有效”?如果我通过 {"user": "chirag", "seven": [1,2,3,4,5,6,7]} 它应该返回 [[2, 3], [4, 1], [8, 4], [3, 2]]?

标签: python json list dictionary data-structures


【解决方案1】:

将 json 转换为字符串可以应用正则表达式。

import re
coords = []
for c in re.findall( r'\[([0-9]), ([0-9])*', str(data)):    
    coords.append([int(c[0]), int(c[1])])

坐标:

[[2, 3], [4, 1], [8, 4], [3, 2]]

正则表达式\[([0-9]), ([0-9])*的解释:

  • \[ 匹配 [
  • (...)创建一个组,用了两次。启用c[0]c[1]
  • [0-9]+ 匹配 0-9 之间的所有字符。可以通过[0-9.,] 扩展以包含点或逗号。
  • , 两个坐标之间的空格。
  • * 多次执行此操作。这就是我们循环遍历结果的原因。

【讨论】:

  • 好答案,很巧妙+10
【解决方案2】:

可以使用递归搜索coords

import json


def get_coords(d):
    if isinstance(d, dict):
        for k, v in d.items():
            if k == "coords":
                yield v
            yield from get_coords(v)
    if isinstance(d, list):
        for v in d:
            yield from get_coords(v)


data = '{"foo": {"type": "geo", "coords": [2, 3], "children": [{"type": "geo", "coords": [4, 1], "children": [{"type": "bar", "children": [{"type": "geo", "coords": [8, 4]}]}, {"type": "geo", "coords": [3, 2]}]}]}}'
data = json.loads(data)

out = list(get_coords(data))
print("Solution:", out)

打印:

Solution: [[2, 3], [4, 1], [8, 4], [3, 2]]

【讨论】:

  • 哇,我从未在任何地方看到过from yield 声明!我想我要研究一下!
【解决方案3】:

一种选择可能是递归,将coords 保存在您的数据中。

# 1. Convert json to dict
data = json.loads(data)['foo']
# 2. coords is set with the first coord: [2, 3]
coords = [data['coords']]

def get_solution(data):
  for dictionary in data:
    for key,value in dictionary.items():
      if key == 'coords':
        # Save the next coord
        coords.append(value)
      if key == 'children':
        # Send the next 'children'
        get_solution(value)
  return coords

solution = get_solution(data['children'])
print(solution)

输出:

[[2, 3], [4, 1], [8, 4], [3, 2]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-19
    • 1970-01-01
    • 2020-07-22
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    • 2018-06-24
    相关资源
    最近更新 更多