我有以下代码。
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
。我相信这是与浅拷贝相关的事情。我是对的吗?如果没有那么如何解决这个问题?
答案 0 :(得分:1)
for each in products:
# print each
if each['Product'] in blackList:
products.remove(each)
在这里,您在迭代时修改列表。这会给你意想不到的结果。快速解决方法是:迭代列表的副本:
for each in products[:]:
答案 1 :(得分:1)
您在迭代同一列表时从列表中删除条目。您可以简单地使用列表推导来保留所需的元素:
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]
。
就像我之前说的那样:它不起作用,但它只是一种错觉
答案 2 :(得分:0)
如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