如何更新dicts列表中的dict项目

时间:2015-06-10 15:24:17

标签: python list dictionary

我有这个词典列表,我将其作为主列表维护:

orig_list = [
   { 'cpu': '4', 'mem': '4', 'name': 'server1', 'drives': '4', 'nics': '1' }
   { 'cpu': '1', 'mem': '2', 'name': 'server2', 'drives': '2', 'nics': '2' }
   { 'cpu': '2', 'mem': '8', 'name': 'server3', 'drives': '1', 'nics': '1' }
   ]

但是,我需要对这个dicts列表中的内容执行操作,例如:

def modifyVM(local_list)
    local_temp_list = []
    for item in local_list :
        '''
        Tons of VM processy things happen here.
        '''
        item['cpu'] = 4
        item['notes'] = 'updated cpu'
    local_temp_list.append(item)
    return local_temp_list

temp_list []
for item in orig_list :
    if item['cpu'] < 4
        temp_list.append(item)

result_list = modifyVM(temp_list)

此时,result_list包含:

result_list = [
    { 'cpu': '4', 'mem': '2', 'name': 'server2', 'drives': '2', 'nics': '2' }
    { 'cpu': '4', 'mem': '8', 'name': 'server3', 'drives': '1', 'nics': '1' }
    ]

所以我的问题是:

1)使用orig_list的结果更新result_list的最有效方法是什么?我希望最终得到:

orig_list = [
    { 'cpu': '4', 'mem': '4', 'name': 'server1', 'drives': '4', 'nics': '1' }
    { 'cpu': '4', 'mem': '2', 'name': 'server2', 'drives': '2', 'nics': '2' 'notes': 'updated cpu' }
    { 'cpu': '4', 'mem': '8', 'name': 'server3', 'drives': '1', 'nics': '1' 'notes': 'updated cpu' }
    ]

2)有没有办法在不创建辅助列表的情况下更新orig_list

提前谢谢。

3 个答案:

答案 0 :(得分:1)

集合存储对象的引用。

因此,您发布的代码也在修改“orig_list”中的项目,因为所有列表都存储了对相同原始词典的引用。

至于问题的第二部分,您不需要创建新列表。您可以直接修改对象,下次迭代列表时,您将看到更新的值。

例如:

orig_list = [
   { 'cpu': 4, 'mem': '4', 'name': 'server1', 'drives': '4', 'nics': '1' },
   { 'cpu': 1, 'mem': '2', 'name': 'server2', 'drives': '2', 'nics': '2' },
   { 'cpu': 2, 'mem': '8', 'name': 'server3', 'drives': '1', 'nics': '1' }
   ]

print orig_list

for item in orig_list :
    if item['cpu'] < 4:
        item['cpu'] = 4

print orig_list

第一次印刷的输出:

[{'mem': '4', 'nics': '1', 'drives': '4', 'cpu': 4, 'name': 'server1'},
 {'mem': '2', 'nics': '2', 'drives': '2', 'cpu': 1, 'name': 'server2'},
 {'mem': '8', 'nics': '1', 'drives': '1', 'cpu': 2, 'name': 'server3'}]

第二次印刷:

[{'mem': '4', 'nics': '1', 'drives': '4', 'cpu': 4, 'name': 'server1'},
 {'mem': '2', 'nics': '2', 'drives': '2', 'cpu': 4, 'name': 'server2'},
 {'mem': '8', 'nics': '1', 'drives': '1', 'cpu': 4, 'name': 'server3'}]

答案 1 :(得分:1)

不,您不需要创建单独的列表,只需使用列表理解。

只需遍历列表并检查cpu键的值是否小于4.如果value小于4,则将cpu键的值更新为4并添加一个额外的键{{ 1}}的值为notes。迭代结束后'updated_cpu'的值是期望的结果。

orig_list

答案 2 :(得分:0)

感谢您的所有输入!我将eugenioy的帖子标记为答案,因为他首先发布了帖子。他和Rahul Gupta的答案都是更新词典列表的非常有效的方法。

然而,我一直在尝试其他方式,因为这些答案虽然效率高,仍然做另外一件事我总是被告知是禁忌:修改你正在迭代的列表。

请记住,我还在学习Python。因此,如果我的一些“启示”是真的,那么它们就是新的,并且对我来说“哇”。为此,我正在添加我实际上最终实现的答案。

这是完成的代码:

def modifyVM(local_list, l_orig_list)
    for item in local_list[:] :
    l_orig_list.remove(item)
        '''
        Tons of VM processy things happen here.
        '''
        item['cpu'] = 4
        item['notes'] = 'updated cpu'
    l_orig_list.append(item)

temp_list []
for item in orig_list[:] :
    if item['cpu'] < 4
        temp_list.append(item)

modifyVM(temp_list, orig_list)

我更改了这一行:

def modifyVM(local_list)

到这一行:

def modifyVM(local_list, l_orig_list)

通过这种方式,我将传递我想要使用的列表以及我想要更新的列表。

接下来我改变了:

for item in local_list :

到这一行:

for item in local_list[:] :

这会导致“item”遍历包含所有内容的“local_list”的切片(副本)。

我还补充说:

l_orig_list.remove(item)

l_orig_list.append(item)

这解决了我的几个问题。

1)这避免了修改任何正在迭代的列表的可能性。

2)这允许在进程发生时更新“orig_list”,这会减少创建和维护的“辅助列表”。

3)传递给函数的“orig_list”和“l_orig_list”是链接变量,直到硬分配(即l_orig_list ='nothing')为止。 (再次感谢所有回答的人!这对我来说是一个很好的“秘密酱”,你们都指出了。)所以,避免“=”,我能够更新“l_orig_list”并拥有“orig_list”也已更新。

4)如果需要,这也允许项目从一个列表移动到另一个列表(即生成错误的列表项可以从“orig_list”中删除并放在任何其他列表中,例如“bad_list”。

最后,我想表彰Steven Rumbalski。当我读到你的评论时,我就像是,“当然!!!”但是,在我意识到字典无法排序之前,我花了两天时间。我不得不缩小我面临的技术问题,在这里提出一个问题。排序是脚本其他部分的未说明要求。如此伟大的建议,我可能会将其用于另一个脚本。