我有這本字典,key, value其中有一對value嵌套串列。根據條件,如果key在value物件的串列中找不到,我想要remove它。
我所做的是:
for key, value in example.items():
for val in value:
if key not in val:
value.remove(val)
我不明白的是,為什么這對第一key, val對有效,但對第二對無效?如下...
example = {"a": [["a", "b", "c", "d"],
["e", "f", "g", "h"],
["a", "i", "j", "k"],
["f", "y", "a", "q"],
["a", "b", "c", "d"],
["e", "f", "b", "h"],
["a", "i", "j", "k"],
["o", "p", "a", "l"]],
"b": [["a", "b", "c", "d"],
["e", "f", "b", "h"],
["a", "i", "j", "k"],
["o", "p", "a", "l"],
["a", "b", "c", "d"],
["e", "f", "g", "h"],
["a", "i", "j", "k"],
["f", "y", "a", "q"]]}
使用輸出上方的代碼塊是:
{'a': [['a', 'b', 'c', 'd'], ['a', 'i', 'j', 'k'], ['f', 'y', 'a', 'q'], ['a', 'b', 'c', 'd'], ['a', 'i', 'j', 'k'], ['o', 'p', 'a', 'l']], 'b': [['a', 'b', 'c', 'd'], ['e', 'f', 'b', 'h'], ['o', 'p', 'a', 'l'], ['a', 'b', 'c', 'd'], ['a', 'i', 'j', 'k']]}
我遇到過這個一個班輪,它似乎作業正常(假設指定元素的索引是一致的)-
for k,v in my_dict.items():
my_dict[k] = list(filter(lambda x: x[0] == k, v))
但是為什么不能remove按上述示例的預期作業?
uj5u.com熱心網友回復:
實際上,它甚至不適用于第一個元素。核心問題是你改變了你正在迭代的串列,特別是這個:
for val in value:
if key not in val:
value.remove(val)
這里發生的事情是,在內部,迭代器是使用索引實作的。這意味著什么顯示以下示例:
In [36]: lst = [0,1,2,3]
In [37]: for item in lst:
...: lst.remove(item)
...:
In [38]: lst
Out[38]: [1, 3]
請注意,在第一次迭代時,您正在處理第 0 個元素,并洗掉該元素。在此迭代結束時,內部索引增加到 1。但是,通過洗掉第 0 個元素,整個串列將被移動,因此您實際上跳過了現在位于第 0 個位置的元素“1”。類似的事情再次發生跳過'3'。
請注意,這是標準 python 實作的行為(通常我認為該行為是未定義的。
在您的情況下發生的情況是,在第一種情況下,不評估被洗掉元素之后緊隨其后的所有元素(如上面的虛擬情況)。'a'和'b'串列之間的唯一區別是,在'a'串列的情況下,緊接洗掉串列之后的所有串列都包含'a'無論如何,因此您不希望將它們洗掉(即,您在評估期間跳過它們無關緊要。
解決此問題的簡單方法是創建您正在迭代的串列的副本:
for val in list(value):
if key not in val:
value.remove(val)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/373973.html
