如何遍历 JSON 中的值并分配给另一个字典

How to loop through values in JSON and assign to another dictionary

我正在开发 Python/Django 网络应用程序。我正在尝试将 JSON 解析为 python 字典,读取字典中的值,如果满足某些条件,则将值分配给另一个字典。

JSON 结构如下:

{content: {cars: [0, 1, 2]}, other_stuff: []}

每辆车都有多个属性:

0: {"make", "model", "power"...}

每个属性有三个变量:

make: {"value": "Toyota", "unit": "", "user_edited": "false"} 

我正在尝试将 JSON 中的值分配给其他词典; car_0、car_1 和 car_2。在这种情况下,考虑到每辆车,JSON 响应在其他方面是相同的,但是第一辆车的 'make' 更改为 'Nissan',然后我试图更改 car_0 也改为 'Nissan'。我正在按以下方式解析 JSON:

    local_cars = [car_0, car_1, car_2] # Dictionaries which are already initialized.

    print(local_cars[0] is local_cars[1]) # Prints: false
    print(local_cars[0]['make']['value']) # Prints: Toyota (yes)
    print(local_cars[1]['make']['value']) # Prints: Toyota (yes)
    print(local_cars[2]['make']['value']) # Prints: Toyota (yes)
    
    counter = 0
    
    if request.method == 'POST':
        payload = json.loads(request.body)
        if bool(payload):
            print(len(local_cars)) # Prints: 3
            print(counter, payload['cars'][0]['make']['value']) # Prints: Nissan (yes)
            print(counter, payload['cars'][1]['make']['value']) # Prints: Toyota (yes)
            print(counter, payload['cars'][2]['make']['value']) # Prints: Toyota (yes)
            print(counter, local_cars[0]['make']['value']) # Prints: Toyota (yes)
            print(counter, local_cars[1]['make']['value']) # Prints: Toyota (yes)
            print(counter, local_cars[2]['make']['value']) # Prints: Toyota (yes)
            for target_car in payload['cars']: # Loop through all three cars in payload
                print(local_cars[0] is local_cars[1]) # false
                for attr in target_car.items(): # Loop through all key:dict pairs of a single car
                    attribute_key = attr[0] # Key (eg. 'make')
                    vars_dict = attr[1] # Dictionary of variables ('value': 'xx', 'unit': 'yy', 'user_edited': 'zz')
                    if vars_dict['user_edited'] == 'true':
                        local_cars[counter][attribute_key]['user_edited'] = 'true'
                        local_cars[counter][attribute_key]['value'] = vars_dict['value']
                print(counter, local_cars[counter]['make']['value']) # Prints: 0, Toyota (yes), 1, Nissan (no!), 2, Nissan (no!)              
                counter = counter + 1

我不明白的是为什么其他车 local_cars[1] 和 local_cars[2] 无论如何都会受到影响。可以看出,由于某种原因,它们的 'make' 更改为 'Nissan',即使它在请求正文中是 'Toyota'。这似乎发生在第一轮'for target_car in payload['cars'].

放弃loop/counter专注于一辆车并没有什么区别:

for target_car in payload['cars']: --> target_car = payload['cars'][0]: 
...
local_cars[0][attribute_key]['user_edited'] = 'true'
local_cars[0][attribute_key]['value'] = vars_dict['value'] 

我做错了什么? car_1 和 car_2 如何受到影响,即使我更改了代码的唯一部分,其中编辑了这些词典中的任何值以仅影响 local_cars[0]?

已更新

收到了正确答案。在最初发布的部分代码之前,我初始化了 car_0、car_1 和 car_2 字典。

我之前做的是:

default_car = model_to_dict(Car.objects.first())
    
    car_0 = {}
    car_1 = {}
    car_2 = {}
    
    attribute = {}
    
    i = 0
    for key, value in default_car.items():
        if i > 1:
            attribute[key] = {"value": value, "unit": units.get(key), "user_edited": "false"}
        i = i + 1
        
    car_0.update(attribute)
    car_1.update(attribute)
    car_2.update(attribute)
    
    local_cars = [car_0, car_1, car_2]
    ...

显然问题是所有 car_x 都与属性字典有关。我通过将 car_x 初始化编辑为以下内容解决了这个问题:

default_car = model_to_dict(Car.objects.first())
    
    car_0 = {}
    car_1 = {}
    car_2 = {}
    
    attribute_0 = {}
    attribute_1 = {}
    attribute_2 = {}
    
    i = 0
    for key, value in default_car.items():
        if i > 1:
            attribute_0[key] = {"value": value, "unit": units.get(key), "user_edited": "false"}
            attribute_1[key] = {"value": value, "unit": units.get(key), "user_edited": "false"}
            attribute_2[key] = {"value": value, "unit": units.get(key), "user_edited": "false"}
        i = i + 1
        
    car_0.update(attribute_0)
    car_1.update(attribute_1)
    car_2.update(attribute_2)
    
    local_cars = [car_0, car_1, car_2]
    ...

我认为你可能没有复制 car_0 等。不要忘记 python 赋值纯粹是 name-binding.

x = car_0
y = car_0
print( x['make']['value'] ) # 'Toyota'
print( y['make']['value'] ) # 'Toyota'
print( x is y ) # True. Both names refer to the same object
x['make']['value'] = 'foo'
print( y['make']['value'] ) # 'foo'

应该是 y = car_0.copy() 甚至 y=car_0.deepcopy()

我没有完全遵循您的代码,但如果您仍然不确定,请进行一些 is 测试以找出哪些实体绑定到同一对象(并且不应该绑定)。