-1

I have the following piece of code.

json_tree = {
  "MyHouseHold": {
    "Kitchen": {
      "@myid": "1.3.61",
      "BakingOven": {
        "@myid": "1",
        "InfoList": {
          "Notice": {
            "@noticelist": "10/TimeToCookTheChicken/20/TimetoCookSalmon",
            "@myid": "2"
          }
        },
        "state": "0",
        "Tid": "3"
      },
      "state": "0",
      "Tid": "2"
    },
    "Tid": "1",
    "state": "0"
  }
}
def yield_output(d):   
    container = {'Tid': d['Tid'],
                 'state': d.get('state')
                 }

    temp_result = d.get('InfoList', {}).get('Notice')
    # If temp_result is a dict (not None), then we can get `@noticelist`
    if temp_result is not None:
        container['noticelist'] = temp_result.get('@noticelist')

    container['state'] = d.get('state')
    return container


def get_output(d, id):
    # Iterate over the json_tree  to return the
    # 'Tid' and 'state' and 'noticelist' information for the requested 'Tid'
    if isinstance(d, dict) and d.get('Tid') == id:
       yield yield_output(d)
    for i in getattr(d, "values", lambda: [])():
        yield from get_based_on_id(i, id)

So, basically for a given Tid, when the get_output function is called the output is as the following.

key_list = list(get_based_on_id(json_tree, 3))
jsonify(key_list)

"Jsonify Output":
{
  "Tid": "3", 
  "state": "0", 
  "noticelist": "10/TimeToCookTheChicken/20/TimetoCookSalmon"
}

The issue is that I want to be able to modify the noticelist to have an output which looks sometime like the following. "noticelist": "{10,TimeToCookTheChicken},{20,TimetoCookSalmon}"

Thus my final output should be something like the following:

"Jsonify Output":
{
  "Tid": "3", 
  "state": "0", 
  "noticelist": "{10,TimeToCookTheChicken},{20,TimetoCookSalmon}"
}

I am unsure on how to modify the def yield_output(d) to reflect the desired output.

Any help would be appreciated.

Yevhen Kuzmovych
  • 10,940
  • 7
  • 28
  • 48
Laura Smith
  • 293
  • 3
  • 13
  • 2
    [split](https://docs.python.org/2/library/stdtypes.html#str.split), [iterate by pairs](https://stackoverflow.com/a/5764807/4727702), [join](https://docs.python.org/2/library/stdtypes.html#str.join). – Yevhen Kuzmovych Sep 18 '19 at 15:22
  • Each part of my comment is a link. There is an answer under "iterate by pairs" link – Yevhen Kuzmovych Sep 18 '19 at 15:24

1 Answers1

-1

You can use recursion with a generator:

def get_notice(d):
   if "@noticelist" in d:
      yield (lambda x:''.join('{'+f'{x[i]},{x[i+1]}'+'}' for i in range(0, len(x), 2)))(d['@noticelist'].split('/'))
   else:
      for b in d.values():
         if isinstance(b, dict):
            yield from get_notice(b)

def get_tid(d, id):
  if int(d.get("Tid", 0)) == id:
     yield {'Tid':id, 'state':d['state'], 'noticelist':list(get_notice(d))[0]}
  else:
     for b in d.values():
       if isinstance(b, dict):
          yield from get_tid(b, id)

print(list(get_tid(json_tree, 3)))

Output:

[{'Tid': 3, 'state': '0', 'noticelist': '{10,TimeToCookTheChicken}{20,TimetoCookSalmon}'}]
Ajax1234
  • 69,937
  • 8
  • 61
  • 102
  • 1
    Sorry, forgot to comment: bad code style, hard to read, long lines, repetitive code blocks, and I have mixed feelings about that usage of lambda, I'd just define a separate function for that. Also, I think that the task is simple enough for the OP to solve by him/her-self with some googling of basic Python functions. Not trying to be mean, just want to keep SO simple and useful :) – Yevhen Kuzmovych Sep 19 '19 at 08:40