Python 为什么remove不处理dicts列表?

Python 为什么remove不处理dicts列表?,python,Python,我有以下代码 import os products = [ {"Product": "S65-85OS04_M2M_GP211_JC222_R6", "PlatformName": "winPc", "PlatformVariant": "eeprom", "DocGeneration": False, "BuildStatus": "Pass", }, {"Produ

我有以下代码

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\u GP221\u JC302\u LTE\u MTN
。我相信这与浅拷贝有关。我是对的吗???如果不是,那么如何解决这个问题

for each in products:
    # print each
    if each['Product'] in blackList:
        products.remove(each)
在这里,您正在修改列表,同时对其进行迭代。这会给你带来意想不到的结果。快速修复方法是:迭代列表的副本:

for each in products[:]:
在这里,您正在修改列表,同时对其进行迭代。这会给你带来意想不到的结果。快速修复方法是:迭代列表的副本:

for each in products[:]:

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

products = [product for product in products 
            if product.get('Product', None) not in blacklist]
或使用
过滤器

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]
正如您所看到的,就在第三次迭代之前,
a
被更新,
3
被移动到第二个位置,并且由于第二个位置已经被迭代,
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]


正如我前面所说的:它不起作用,但它只是一种错觉,它确实起作用了

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

products = [product for product in products 
            if product.get('Product', None) not in blacklist]
或使用
过滤器

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]
正如您所看到的,就在第三次迭代之前,
a
被更新,
3
被移动到第二个位置,并且由于第二个位置已经被迭代,
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]


正如我前面所说的:它不起作用,但它只是一种错觉,它确实起作用了。正如AKS所解释的,您可以使用列表理解来过滤列表元素。此外,您还可以使用内置的
过滤器
功能:

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]

最终,您遇到的问题是,您在迭代列表时正在修改列表。这已经讨论过很多次了,例如:

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

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]

最终,您遇到的问题是,您在迭代列表时正在修改列表。这已经被讨论过很多次了,例如:

但是如果我做
a=[1,2,3,4,5,6,7,8]
并且在a中为e做
:如果e%2==0:a.remove(e)
,那么它工作得很好..为什么???@MayukhSarkar出乎意料->有时它似乎工作得很好,有时它不会。但是如果我做
a=[1,2,3,4,5,6,7,8]如果e%2==0:a.remove(e)
,那么它就工作得很好。为什么???@MayukhSarkar意外->有时它似乎工作得很好,有时它不工作。但是如果我做
a=[1,2,3,4,5,6,7,8]
并且做
对于a中的e:if e%2==0:a.remove(e)
,那么,然后它就很好了…为什么???@MayukhSarkar我用正确的推理更新了我的答案。请看一看。我很乐意帮忙。但是如果我做
a=[1,2,3,4,5,6,7,8]
并且在a中为e做
:如果e%2==0:a.remove(e)
,那么它很好。为什么???@MayukhSarkar我用适当的推理更新了我的答案。请看一下,我很乐意帮忙。