好的,这个问题实际上已经解决了,但是我仍然想知道为什么。我正在尝试从二维数组中删除元素,这是代码:
print("adj in the while loop: ", adj)
for z in adj:
print("for loop: ", z)
if z[-1] is True:
adj.remove(z)
result += 1
print("adj after all execution: ", adj)
控制台输出:
adj in the while loop: [[1, True], [0, 2, True], [1, True]]
for loop: [1, True]
for loop: [1, True]
adj after all execution: [[0, 2, True]]
这不符合预期。执行后正确的输出应为[]
。
因此,我开始使用列表理解来编辑代码。
列表理解代码:
adj = [z for z in adj if z[-1] is not True]
它按预期工作。输出为[]
。
这使我感到困惑。为什么这两种看似相同的方法会产生不同的结果?有人可以向我解释吗?
答案 0 :(得分:4)
这两种方法不相同。在列表理解中,您永远不会调用adj.remove(z)
。
列表理解是在迭代adj
时创建一个新列表,然后在完成后将(空)列表分配回adj
。迭代期间,adj
不会改变,val selectedItem = MediatorLiveData<Voyage>()
var voyages: LiveData<Resource<List<Voyage>>>
var voyageFilter = MutableLiveData<VoyageFilter>()
selectedItem.addSource(voyageFilter) { filter ->
//do something
}
selectedItem.addSource(voyages) { listResource ->
//do something
}
只是在最后一次迭代之后。
答案 1 :(得分:2)
您绝对可以使用.remove()
,但要遍历原始副本而不是原始副本本身:
adj = [[1, True], [0, 2, True], [1, True]]
for z in adj[:]:
print("for loop: ", z)
if z[-1] is True:
adj.remove(z)
result += 1
print("adj after all execution: ", adj)
它将打印出一个空列表。
在这里,我们遍历副本,但从原始副本中删除元素。这样可以避免您的代码出现差异。
答案 2 :(得分:1)
如果在元素上使用方法list
或remove
,则在append
上并与其内部块同时进行迭代是不正确的方法。基本上最好将编码更改为其他方式。就像奥斯汀在他的代码中建议的那样,或者使用单独的索引而不是迭代索引或元素。
那是
adj = [[3, 4, 5, False], [8, 7, False], [0, True], [-1, False], [1, True], [0, 2, False], [0, 2, True], [1, True], [4, False]]
del_index = 0
for i in range(len(adj)):
print("for loop: ", adj[del_index])
if adj[del_index][-1] is True:
adj.remove(adj[del_index])
else:
del_index+=1
print("adj after all execution: ", adj)
过滤器可用于此目的
filter(lambda elem: elem[-1] is True, adj)
这可能会导致系统崩溃,因为将append元素添加到列表并同时在同一元素上进行迭代。
crash_my_system = [0]
for i in crash_my_system: crash_my_system.append(i+1)
不仅对List
如此。这对于所有可变数据结构(例如Dict
)都是通用的。请参阅:Christoph Zwerschke's blog