您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Python减少嵌套循环

Python减少嵌套循环

您的两个外部循环正在创建列表的 组合 。为这些使用itertools.combinations()迭代器。您最里面的双循环会产生笛卡尔积 ,因此请使用itertools.product()迭代器

不要使用range(), just loop directly over the polygon lists; useenumerate()来生成索引以添加索引,而不要使索引相反。

到配对部分,该pairwise()配方itertools食谱部; 这样您就可以使用所有细分。要再次从头开始绕圈(将最后一个坐标与第一个坐标配对),只需将列表的第一个元素附加到末尾即可。

一旦摆脱了嵌套循环,就可以使用break结束循环而不是使用标志变量。

from itertools import combinations, product

def 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)

这不仅现在可读性强,而且还应该更有效!

python 2022/1/1 18:29:17 有431人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶