您的两个外部循环正在创建列表的 组合
。为这些使用
itertools.combinations()迭代器。您最里面的双循环会产生
笛卡尔积
,因此请使用
itertools.product()迭代器。
不要使用
range(), just loop directly over the polygon lists;useenumerate()来生成索引以添加索引,而不要使索引相反。
到配对部分,该
pairwise()配方从
itertools食谱部;
这样您就可以使用所有细分。要再次从头开始绕圈(将最后一个坐标与第一个坐标配对),只需将列表的第一个元素附加到末尾即可。
一旦摆脱了嵌套循环,就可以使用
break结束循环而不是使用标志变量。
from itertools import combinations, productdef pairwise(iterable): "s -> (s0,s1), (s1,s2), (s2, s3), ..." a, b = tee(iterable) next(b, None) return zip(a, b)for (i, a_poly), (j, b_poly) in combinations(enumerate(polygons), 2): for a in a_poly: if isInside(a.x, a.y, b_poly): union(i, j) for b in b_poly: if isInside(b.x, b.y, a_poly): union(j, i) # attach the first element at the end so you go 'round' a_segments = pairwise(a_poly + a_poly[:1]) b_segments = pairwise(b_poly + b_poly[:1]) for a_seg, b_seg in product(a_segments, b_segments): if doIntersect(*a_seg, *b_seg): union(i,j) break
实际上,一旦确定某个东西是一个并集,就不必继续进行其余的测试。您可以使用
any()功能停止测试
isInside()和
doIntersect早期的功能:
for (i, a_poly), (j, b_poly) in combinations(enumerate(polygons), 2): if any(isInside(a.x, a.y, b_poly) for a in a_poly): union(i, j) break # union found, no need to look further for any(isInside(b.x, b.y, a_poly) for b in b_poly): union(i, j) break # union found, no need to look further # attach the first element at the end so you go 'round' a_segments = pairwise(a_poly + a_poly[:1]) b_segments = pairwise(b_poly + b_poly[:1]) if any(doIntersect(*a_seg, *b_seg) for a_seg, b_seg in product(a_segments, b_segments)): union(i,j)
这不仅现在可读性强,而且还应该更有效!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)