Reputation: 1788
Given (x,y)
, I want the collection:
[(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:
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...
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 can solve the practical problem of finding the coords with the bad solution. But I want to grok list comps better.
Upvotes: 2
Views: 925
Reputation: 8510
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
Upvotes: 1
Reputation: 5660
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.
Upvotes: 3