为什么remove不在dict列表上工作?

2024-03-29 05:35:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下代码。你知道吗

import os

products =  [

        {"Product": "S65-85OS04_M2M_GP211_JC222_R6",
         "PlatformName": "winPc",
         "PlatformVariant": "eeprom",
         "DocGeneration": False,
         "BuildStatus": "Pass",
        },

        {"Product": "SC5-01OS19_GP221_JC302_LTE_MTN",
         "PlatformName": "winPc",
         "PlatformVariant": "flash",
         "DocGeneration": False,
         "BuildStatus": "Fail",
         },

        {"Product": "SC5-01OS01_GP211_JC302_LTE_TMO",
         "PlatformName": "winPc",
         "PlatformVariant": "flash",
         "DocGeneration": False,
         "BuildStatus": "Pass",
         }
    ]

class UTE(object):

    def __init__(self, workspace, products, blackList=None):
        for each in products:
            # print each
            if each['Product'] in blackList:
                products.remove(each)
        for each in products:
            print each["Product"]

if __name__ == '__main__':
    ins = UTE('ws', products, ["SC5-01OS01_GP211_JC302_LTE_TMO", "SC5-01OS19_GP221_JC302_LTE_MTN"])

现在每当我运行它时,它只删除dict中的一个条目。例如,在本例中,它删除的是第二个条目,即SC5-01OS19_GP221_JC302_LTE_MTN。我相信这和浅拷贝有关。我说的对吗??如果没有,那么如何解决这个问题?你知道吗


Tags: falseproductproductseachmtnltebuildstatusplatformname
3条回答

正如AKS所解释的,您可以使用列表理解来过滤列表元素。此外,还可以使用内置的filter函数:

some_integers = range(15)

# via filter
odd_integers = filter(lambda i: i%2 != 0, some_integers)

# via list comprehension
odd_integers = [num for num in some_integers if num %2 != 0]

最终,您遇到的问题是,您在遍历列表时正在修改它。这已经讨论过很多次了,例如:Modifying list while iterating

在重复同一个列表时,您正在从列表中删除条目。您可以简单地使用列表理解来保留所需的元素:

products = [product for product in products 
            if product.get('Product', None) not in blacklist]

或使用filter

products = filter(lambda product: product.get('Product', None) not in blacklist, products)

关于从a = [1, 2, 3, 4, 5, 6, 7, 8]删除的更新:

你说以下代码有效:

a = [1, 2, 3, 4, 5, 6, 7, 8]
for e in a:
    if e % 2 = 0:
        a.remove(e)

print(a) # [1, 3, 5, 7]

好吧,它不起作用,但它只是一个幻觉,让我们添加一些打印语句来理解:

for e in a:
    print 'Next Item: ', e
    if e % 2 = 0:
        a.remove(e)

    print 'Current List: ', a

下面是print语句的输出:

Next Item:  1
Current List:  [1, 2, 3, 4, 5, 6, 7, 8]
Next Item:  2
Current List:  [1, 3, 4, 5, 6, 7, 8]
Next Item:  4
Current List:  [1, 3, 5, 6, 7, 8]
Next Item:  6
Current List:  [1, 3, 5, 7, 8]
Next Item:  8
Current List:  [1, 3, 5, 7]

如您所见,就在第3次迭代之前,a被更新,3被移到第2个位置,并且由于第2个位置已经被迭代,3从未进入循环。同样,对于其他循环,循环不会运行8次,而只运行5次。你知道吗

如果更改a中值的顺序,将不会得到相同的行为:

a = [1, 4, 2, 3, 6, 8, 7, 5]

现在,再次运行上面的`for循环:

Next Item:  1
Current List:  [1, 4, 2, 3, 6, 8, 7, 5]
Next Item:  4
Current List:  [1, 2, 3, 6, 8, 7, 5]
Next Item:  3
Current List:  [1, 2, 3, 6, 8, 7, 5]
Next Item:  6
Current List:  [1, 2, 3, 8, 7, 5]
Next Item:  7
Current List:  [1, 2, 3, 8, 7, 5]
Next Item:  5
Current List:  [1, 2, 3, 8, 7, 5]

所以在列表的末尾,a的值是[1, 2, 3, 8, 7, 5]。你知道吗

就像我之前说的:它不起作用,但它只是一个幻觉,它起作用了

for each in products:
    # print each
    if each['Product'] in blackList:
        products.remove(each)

在这里,您可以在遍历列表的同时修改它。那会给你带来意想不到的结果。快速修复方法是:迭代列表的副本:

for each in products[:]:

相关问题 更多 >