问题描述
我想比较一个列表的元素,在每个 for
循环结束时,组合使用新的更新列表继续。
from itertools import combinations
aListe = ['a','b','c','d']
for first,second in combinations(aListe,2):
# do something
aListe.remove(first)
ValueError: list.remove(x): x not in list
更具体的#do something示例。
假设我的列表包含 shapely 多边形,例如
aListe = [polygon1,polygon2,polygon3,polygon4]
for first,2):
if area(first) > area(second):
aListe.remove(first)
如果列表中第一个多边形的面积已经大于第二个,我不希望将它与其他多边形进行比较。我希望下一个 for
循环在没有第一个多边形的更新列表上开始。
解决方法
如您所见,您的代码失败了,因为 itertools.combinations
多次访问每个列表项并且它只能被删除一次(假设它只包含一次)。
但即使您添加了 if first in aList
之类的检查来规避此错误,您也可能会得到意想不到的结果,这通常是在迭代列表时从列表中删除项目的情况,请参阅 {{3} }.
在您的情况下,我不会将多边形从列表中实际删除,而是通过将其添加到“已删除”集中来将其标记为“已删除”,如果再次遇到已删除的多边形,则跳过迭代。>
(注意,为了将多边形添加到集合中,如果我正确理解 Removing from a list while iterating over it,"[...] 使用几何 ID 作为键,因为匀称的几何本身是不可散列的。")
from itertools import combinations
removed = set()
aListe = [polygon1,polygon2,polygon3,polygon4]
for first,second in combinations(aListe,2):
if id(first) in removed:
continue
if area(first) > area(second):
removed.add(id(first))