繁体   English   中英

如何更新字典列表中的字典项目

[英]How to updating dict items inside a list of dicts

我有这个我作为主列表维护的字典列表:

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

先感谢您。

集合存储对对象的引用。

因此,您发布的代码也已经在修改“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'}]

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

只需遍历列表并检查cpu键的值是否小于 4。如果值小于 4,则将cpu键的值更新为 4 并添加一个值为'updated_cpu'的额外关键notes 迭代完成后orig_list值就是想要的结果。

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

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

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

感谢您的所有投入! 我将 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 = 'anything')。 (再次感谢所有回答的人!这对我来说是一些很棒的“秘诀”学习,你们都指出了这一点。)所以,避免“=”,我能够更新“l_orig_list”并有“orig_list”也更新了。

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

最后,我要感谢 Steven Rumbalski。 当我读到你的评论时,我想,“当然!!!” 但是,我花了 2 天的时间才意识到无法对字典进行排序。 我不得不缩小我在这里提出问题所面临的技术问题的范围。 排序是脚本其他部分的未说明要求。 这么好的建议,我可能会将它用于另一个脚本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM