0

I have a program that will loop through a set of nested dictionaries and lists to get to a value. Along the way, I try to store the index or key in a List.

In another file, I want to use those list of Keys to get to a value in the same location and copy it over.

I'm not quite sure how to do this. I'll provide my current code though.

import json

# o_name = input("What is the json file name to transfer info from?")
o_name = "fu"
o_file = open(o_name + ".json", "r")
o_json = json.load(o_file)

# t_name = input("What is the json file name to copy the info to?")
t_name = "bar"
t_file = open(t_name + ".json", "r")
t_json = json.load(t_file)

key_list = []

def nested_values_iterator(obj):
    global key_list

    # Iterate over all values of given dictionary
    if isinstance(obj, list):
        for index, value in enumerate(obj):
            key_list.append(index)
            # If value is list then iterate over all its values
            for v in nested_values_iterator(value):
                yield v
        if len(key_list) > 0:
            print("popping list " + str(key_list.pop()))
    elif isinstance(obj, dict):
        for value in obj:
            key_list.append(value)
            # If value is dict then iterate over all its values
            for v in nested_values_iterator(obj[value]):
                yield v
        if len(key_list) > 0:
            print("popping dictionary " + str(key_list.pop()))
    else:
        yield obj
        key_list.pop()


for data in nested_values_iterator(o_json):
    # Copy the info over
    print(key_list)
    print("data: " + str(data))
    entry = t_json
    for key in key_list[0:len(key_list)-1]:
        entry = entry[key]
        try:
            if type(entry) == dict:
                print("entry: " + str(entry[key_list[-1]]) + " = " + str(data))
                entry[key_list[-1]] = data
            elif type(entry) == list:
                print("entry: " + str(entry[key_list[-1]]) + " = " + str(data))
                entry[key_list[-1]] = data
        except:
            break

    t_file = open(o_name + ".json", "w")
    t_file.write(json.dumps(t_json, indent=2, sort_keys=False))

fu.json

{
  "someList": [
    "this",
    "is",
    "a",
    "test",
    "fubar",
    1
  ],
  "numbers": 3,
  "AddedInfo": {
    "deeperDict": {
      "level": 3
    },
    "deeperList": [
      4.4,
      123.4
    ]
  }
}

bar.json:

{
  "someList": [
    "this",
    "test",
    "didnt",
    "work",
    "bufar",
    2
  ],
  "numbers": 3,
  "AddedInfo": {
    "deeperDict": {
      "level": 3
    },
    "deeperList": [
      4.4,
      123.4
    ]
  }
}

printed outcome

['someList', 0]
data: this
entry: this = this
['someList', 1]
data: is
entry: test = is
['someList', 2]
data: a
entry: didnt = a
['someList', 3]
data: test
entry: work = test
['someList', 4]
data: fubar
entry: bufar = fubar
['someList', 5]
data: 1
entry: 2 = 1
popping list someList
['numbers']
data: 3
['AddedInfo', 'deeperDict', 'level']
data: 3
popping dictionary deeperDict
['AddedInfo', 'deeperList', 0]
data: 4.4
['AddedInfo', 'deeperList', 1]
data: 123.4
popping list deeperList
popping dictionary AddedInfo

The result is that there is no change to the data in the designated transfer file. My theory is that the entry variable is referring to a copy of the entry, instead of the place in the file where the actual entry is stored.

As an added, my current system for getting the keys and values needs work, and any help to improve that is also appreciated.

  • I would start with [this implementation](https://stackoverflow.com/a/22699047/15452601) and work on the loaded dicts directly, without constructing a general iterator (which is possible, but will only complicate this use-case where it's not clear how to handle e.g. dicts on one side and lists on the other – 2e0byo Oct 09 '21 at 13:08
  • Can you provide sample input/output? – vnk Oct 09 '21 at 13:28
  • @vnk ['common', 0] data: pixelmon:mint_seeds ['common', 1] data: pixelmon:xs_exp_candy ['common', 2] data: pixelmon:s_exp_candy ['common', 3] data: pixelmon:absorb_bulb ['common', 4] – Loren Hickerson Oct 10 '21 at 13:27
  • This doesn't seem clear enough. Please add the data in your question if possible. – vnk Oct 10 '21 at 15:31
  • @vnk I did some edits to the original code. I figured some of it out, but am now realizing my new code solution doesn't result in any change to the file. Print statements suggest that it will work. But I believe the variable is referring back to a copy of the data and not the point where the data is in the file in order to make the change. So I need some way to make that happen. I will update it with output files tho. – Loren Hickerson Oct 11 '21 at 11:10
  • Actually, it does make a change to the first list, but that's the only thing it transfers info from. – Loren Hickerson Oct 11 '21 at 12:23

0 Answers0