简体   繁体   English

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

[英]Double list comprehension in Python - finding borders coordinates

Given (x,y) , I want the collection: 给定(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)]

(I don't really care if it is a list, set, or any other type of collection.) (我真的不在乎它是列表,集合还是任何其他类型的集合。)

I've experimented with several permutations of list comps, nothing has really worked. 我已经尝试了列表组合的几种排列,但实际上没有任何作用。

I found a BAD solution:: 我找到了一个糟糕的解决方案::

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]

But I really hate this solution and am wondering if there is a more direct approach. 但是我真的很讨厌这种解决方案,并且想知道是否有更直接的方法。

EDIT 编辑

The BAD solution can be made better, as mentioned below in comments: 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]

But the problem remains --- i'm just getting all the coords and then dropping the ones that aren't in the comp... 但是问题仍然存在---我只是得到所有的坐标,然后丢掉那些不在计算机中的坐标。

EDIT 编辑

The BAD solution can be made better still... 可以使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]

But I don't know how I feel about this... 但是我不知道我对此感觉如何...

EDIT -- what I really want to know is... 编辑-我真正想知道的是...

Is there a way to do some kind of (I dunno) recursive or loopy list comprehension that returns the desired results by directly building the list? 有没有一种方法可以进行某种(I dunno)递归或循环列表理解,通过直接构建列表来返回所需的结果?

I can solve the practical problem of finding the coords with the bad solution. 我可以解决解决问题的实际问题。 But I want to grok list comps better. 但我想更好地列出清单。

If you really want a list comprehension here's one. 如果您真的想要列表理解,这里就是一个。

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

This will return a sorted set of tuple s. 这将返回一个排序settuple秒。

as list comprehension perhaps like this 作为列表理解也许像这样

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 ]

But I rather produce directly what I need instead of searching for some esoteric and/or potentially inefficient way of doing it, is better to be clear than clever. 但是我宁愿直接产生我所需要的东西,而不是寻找一些深奥的和/或可能效率低下的方法,要比清楚更清楚。

Like this 像这样

def border(x,y):
    for p in range(x+1):
        yield (p,0)
        yield (p,y)
    for p in range(1,y):
        yield (0,p)
        yield (x,p)

and this one is way more efficient as it don't waste time producing unnecessary stuff just to be discarded 而且这种方法效率更高,因为它不会浪费时间来生产不必要的东西,而只是将其丢弃

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM