Reputation: 5812
What would be a pretty way to indent/format the line in the function below? Or should I not be trying to write this as a one liner at all?
def rects_bound(rects):
""" Returns a rectangle that bounds all given rectangles
"""
return reduce(lambda (ax,ay,aw,ah), (bx,by,bw,bh): (min(ax,bx),
min(ay,by),
max(ax+aw, bx+bw),
max(ay+ah, by+bh)), rects)
or maybe
def rects_bound(rects):
""" Returns a rectangle that bounds all given rectangles
"""
return reduce(lambda (ax,ay,aw,ah),
(bx,by,bw,bh): (min(ax,bx), min(ay,by),
max(ax+aw, bx+bw), max(ay+ah, by+bh)),
rects)
I usually just kind of "get creative" in these situations, and I know there is probably no "right" way, I'm just interested in your opinions and habits.
Upvotes: 1
Views: 476
Reputation: 82924
Your lambda function is wrong. To fix it would make it even longer and involve redundant computation. Use a def instead:
def rects_bound(rects):
""" Returns a rectangle that bounds all given rectangles
"""
def bound_2_rects((ax, ay, aw, ah), (bx, by, bw, bh)):
x = min(ax, bx)
y = min(ay, by)
return x, y, max(ax+aw, bx+bw) - x, max(ay+ah, by+bh) - y
return reduce(bound_2_rects, rects)
Upvotes: 1
Reputation: 208425
I would suggest the following:
def rects_bound(rects):
""" Returns a rectangle that bounds all given rectangles
"""
return reduce(lambda (X,Y,W,H), (x,y,w,h): (min(X,x), min(Y,y),
max(X+W, x+w),
max(Y+H, y+h)), rects)
Reducing each argument to a single character really saves on space which helps this look cleaner. Another option would be to define the lambda function on a separate line (possibly even with def
) so that the arguments aren't that far over in the first place.
Upvotes: 0
Reputation: 66940
If you're worried about long lines, don't use a lambda
. Use a regular named function instead.
def rects_bound(rects):
""" Returns a rectangle that bounds all given rectangles
"""
def bounding_rect_reducer((ax, ay, aw, ah), (bx, by, bw, bh)):
return (min(ax,bx),
min(ay,by),
max(ax+aw, bx+bw),
max(ay+ah, by+bh))
return reduce(bounding_rect_reducer, rects)
Upvotes: 2
Reputation: 601489
First of all, avoid long lines if possible. This particular example could be written much more readably as
def rects_bound(rects):
x0 = min(x for x, y, w, h in rects)
y0 = min(y for x, y, w, h in rects)
x1 = max(x + w for x, y, w, h in rects)
y1 = max(y + h for x, y, w, h in rects)
return x0, y0, x1, y1
If you prefer to avoid the variables, you could also use
def rects_bound(rects):
return (min(x for x, y, w, h in rects),
min(y for x, y, w, h in rects),
max(x + w for x, y, w, h in rects),
max(y + h for x, y, w, h in rects))
which I still find much more readable than your original code.
(Note that I assume rects
allows multiple iterations.)
Upvotes: 4
Reputation: 2230
I think this depends on the programmer and on the situation but I usually don't like to allocate a variable just to have shorter lines.
Looking at your 2 examples, I would go for the second one, or this one:
def rects_bound(rects):
""" Returns a rectangle that bounds all given rectangles
"""
return reduce(
lambda (ax,ay,aw,ah), (bx,by,bw,bh):
(min(ax,bx), min(ay,by), max(ax+aw, bx+bw), max(ay+ah, by+bh)
),
rects
)
Upvotes: 2