Python中的双列表理解 - 查找边框坐标

时间:2017-01-06 01:05:59

标签: python

鉴于(x,y),我想要收集:

[(0,0),(0,y),(1,0),(1,y),(2,0),(2,y)...(x-1,0),(x-1,y),(x,0),(x,y),
             (0,1),(x,1),(0,2),(x,2)...(0,y-1),(x,y-1)]

(我真的不在乎它是列表,集合还是任何其他类型的集合。)

我已尝试过列表组合的几种排列,但没有真正有效。

我找到了一个BAD解决方案::

all_points = list(itertools.product([x for x in range(x+1)], [y for y in range(y+1)]))
border = [xy for xy in all_points if xy[0]==0 or xy[0]==x or xy[1]==0 or xy[1]==y]

但我真的很讨厌这个解决方案,我想知道是否有更直接的方法。

修改

BAD解决方案可以做得更好,如下面的评论所述:

all_points = list(itertools.product(range(x+1), range(y+1))
border = [xy for xy in all_points if xy[0]==0 or xy[0]==x or xy[1]==0 or xy[1]==y]

但问题仍然存在 - 我只是得到所有的坐标,然后放弃那些不属于补偿的坐标......

修改

BAD解决方案可以做得更好......

border = [xy for xy in itertools.product(range(x+1), range(y+1)) if xy[0]==0 or xy[0]==x or xy[1]==0 or xy[1]==y]

但我不知道我对此感觉如何...

编辑 - 我真正想知道的是......

有没有办法做某种(我不知道)递归或循环列表理解,通过直接构建列表返回所需的结果?

我可以解决找不到解决问题的实际问题。但我想更好地了解列表组合。

2 个答案:

答案 0 :(得分:3)

如果你真的想要一个列表理解,那么就是一个。

l = sorted({j for i in [[[(i, y), (i, 0)] for i in range(x+1)] + [[(x, i), (0, i)] for i in range(y+1)]][0] for j in i})

这将返回settuple的已排序{。}}。

答案 1 :(得分:1)

作为列表理解或许像这样

Int

但我宁愿直接生产我需要的东西,而不是寻找一些深奥的和/或潜在的低效率的方法,最好是聪明而不是聪明。

喜欢这个

def border(x,y):
    return [ (a,b) for a in range(x+1) for b in range(y+1) if 0 in (a,b) or x==a or y==b ]

这个方法更有效率,因为它不会浪费时间生产不必要的东西而只是为了被丢弃