删除所有嵌套的JSON数组,但最小值为d的数组除外

2024-05-14 20:21:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我有下面的JSON字典。 我想做的是删除所有“近距离接近数据”的物体,其中“轨道天体”不是“地球”。 问题是可能有不止一个物体绕着地球轨道运行,在所有这些物体之间,我尽量保持一个最小的“接近日期”。你知道吗

data = [
  {
    "id": "01",
    "close_approach_data": [
      {
        "orbiting_body": "Earth",
        "approach_date": "1945-06-07"
      },
      {
        "orbiting_body": "Earth",
        "approach_date": "1975-06-07"
      },
      {
        "orbiting_body": "Mars",
        "approach_date": "1935-06-07"
      }
    ]
  },
{
    "id": "02",
    "close_approach_data": [
      {
        "orbiting_body": "Earth",
        "approach_date": "1945-06-07"
      },
      {
        "orbiting_body": "Earth",
        "approach_date": "1975-06-07"
      },
      {
        "orbiting_body": "Mars",
        "approach_date": "1935-06-07"
      }
    ]
  }
]

我想得到这个:

data = [
  {
    "id": "01",
    "close_approach_data": {
      "orbiting_body": "Mars",
      "approach_date": "1935-06-07"
    }
  },
  {
    "id": "02",
    "close_approach_data": {
      "orbiting_body": "Mars",
      "approach_date": "1935-06-07"
    }
  }
]

所以我试着想出一些代码:

earthObjs =[]
for element in data:
    for subel in element["close_approach_data"]:
        if ([subel][0]["orbiting_body"]=="Earth"):
            #then i would have to store the objects
            earthObjs.append([subel])

    #here i am trying to find the object with the min 'approach_date'
    minEarth = min(dt.strptime(earthObjs["close_approach_date"],"%Y-%m-%d"))

    #then i would have to somehow place this as the only element of close_approach_data
    element["close_approach_data"] = json.loads(minEarth)

    #and clear the earthObjs list so it can be used for the next element
    earthObjs.clear()

我很清楚我的代码有一半不起作用。我想我可能终于快成功了,我真的需要一些帮助。具体来说,我知道我在搜索min时出错了,因为我无法访问对象的'close_approach_data'字段。 另外,我也不确定json.loads行。你知道吗


Tags: theidforclosedatadatebodyelement
2条回答

这是实现算法的一种方法:

res = []

for d in data:
    res.append({**{'id': d['id'], **{'close_approch_data': \
    next((iter(sorted((e for e in d['close_approach_data'] \
                      if e['orbiting_body'] != 'Earth'), \
                     key=lambda x: x['approach_date']))), None)}}})

print(res)

[{'close_approch_data': {'approach_date': '1935-06-07',
                         'orbiting_body': 'Mars'},
  'id': '01'},
 {'close_approch_data': {'approach_date': '1935-06-07',
                         'orbiting_body': 'Mars'},
  'id': '02'}]

解释

乍一看(第二眼),这看起来是一团糟。但关键部分是:

  • 重复你的字典列表。你知道吗
  • 对于每个id,在列表res中添加一个项。你知道吗
  • 仅在生成器表达式中通过if子句包含非来自地球的数据。你知道吗
  • 按进场日期排序;您可以继续使用datetime,但鉴于当前格式,这不是必需的。你知道吗
  • 如果第一个元素通过next(iter(...))存在,则提取它。如果不存在元素,则返回{'close_approach_data': None}。你知道吗

下面是将您描述的处理过程相当直接地转换为代码:

from datetime import datetime
import json

for dataset in data:
    earliest, initial = datetime.max, {}

    # Find the non-Earth body with the earliest approach date.
    for close_approach in dataset["close_approach_data"]:
        if close_approach["orbiting_body"] != "Earth":
            dt = datetime.strptime(close_approach["approach_date"],
                                   "%Y-%m-%d")
            if dt < earliest:
                dt, initial = earliest, close_approach

    # Replace entire close_approach_data list with a single object
    # comprised of the non-Earth item with the earliest date (or an
    # empty dictionary if there weren't any).
    dataset["close_approach_data"] = initial

print(json.dumps(data, indent=4))

输出:

[
    {
        "id": "01",
        "close_approach_data": {
            "orbiting_body": "Mars",
            "approach_date": "1935-06-07"
        }
    },
    {
        "id": "02",
        "close_approach_data": {
            "orbiting_body": "Mars",
            "approach_date": "1935-06-07"
        }
    }
]

相关问题 更多 >

    热门问题