【问题标题】:how to update whole part after matched匹配后如何更新整个部分
【发布时间】:2018-10-31 19:11:15
【问题描述】:

关于Update a value when matched in array的进一步问题

data=[{"hostname":"a.example.com","Id":"1"},{"hostname":"b.example.com","Id":"2"},{"hostname":"c.example.com","Id":"1"},{"hostname":"d.example.com","Id":"1"}]

update={"hostname":"c.example.com","Id":"10"}

for item in data:
    if item['hostname'] == 'c.example.com':
       item = update

print(data)

为什么输出没有更新

[{'hostname': 'a.example.com', 'Id': '1'}, {'hostname': 'b.example.com', 'Id': '2'}, {'hostname': 'c.example.com', 'Id': '1'}, {'hostname': 'd.example.com', 'Id': '1'}]

为什么item['Id'] = 10 有效,而item = update 无效?

如何解决?

【问题讨论】:

    标签: python json python-3.x list dictionary


    【解决方案1】:

    需要删除data中的元素并追加update

    data=[{"hostname":"a.example.com","Id":"1"},{"hostname":"b.example.com","Id":"2"},{"hostname":"c.example.com","Id":"1"},{"hostname":"d.example.com","Id":"1"}]
    
    update={"hostname":"c.example.com","Id":"10"}
    
    for item in data:
        if item['hostname'] == 'c.example.com':
            data.remove(item) # remove the condition satisfied element
            data.append(update) # append the update
    
    print(data)
    

    解释:

    此处的= 运算符不会更新您的data 元素。所以你可以使用removeappend 删除旧的并添加新的。

    当您使用item = update 时,这意味着您正在使item 引用{"hostname":"c.example.com","Id":"10"},但不会更新实际的data

    输出:

    [{'hostname': 'a.example.com', 'Id': '1'}, {'hostname': 'b.example.com', 'Id': '2'}, {'hostname': 'd.example.com', 'Id': '1'}, {'hostname': 'c.example.com', 'Id': '10'}]
    

    【讨论】:

    • @Bill:你说清楚了吗?
    • 为什么item['Id'] = 10 可以直接在data 中工作和更新?
    • @Bill:当您执行item['Id'] = 10 时,您正在通过指定使用相应的键来更新字典项的值。所以它在data 中得到更新。
    • @Bill:我更新了我的解释。让我知道你需要澄清吗?
    【解决方案2】:

    x = something

    如果你有分配给 x 的东西,例如x = object1,那么如果你写x = object2,这不会以任何方式影响object1*(或任何其他数据)。这只是意味着变量x 现在指向不同的对象(object2 而不是object1)。

    x.y = something

    另一方面,x.y = something 确实会影响数据(一般情况下)。它修改x 中的数据。它仍然不会修改以前在 x.y* 中的数据 - x.y 不再引用旧数据。

    x['y'] = something

    这与x.y = something 的语义非常相似。

    原始示例

    for item in data:
        if item['hostname'] == 'c.example.com':
           item = update
    

    item = update 之后,变量item 不再引用data 中的项目,它引用了一个不同的变量:update。如果你print(item) 你会看到的。

    之后执行的行是for item in data,它再次更改了item 引用的内容,从而有效地取消了前一行。

    你真正想要的是修改data,所以你应该这样做,例如

    for i in range(len(data)):
        ...
        data[i] = update
    

    (*) 虽然原始数据没有被修改,但它可能会被“删除”,即如果它不再被任何变量引用,它的内存可能会被释放,因为它不再需要了。

    【讨论】:

      【解决方案3】:

      赋值 (=) 不会更改变量。

      这里有 2 个选项可以解决这个问题:

      1. 更改列表而不是列表中的项目:

      for i in range(len(data)): if data[i]['hostname'] == 'c.example.com': data[i] = update

      1. 更新字典本身。 (update 是就地方法)

      for item in data: if item['hostname'] == 'c.example.com': item.update(update) 这仅在您的 update 变量中的键与项目中的键重叠时才有效。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-07
        • 1970-01-01
        • 1970-01-01
        • 2018-08-11
        • 2022-10-13
        • 1970-01-01
        相关资源
        最近更新 更多