Cleaning up conditionals

Deborah Swanson python at deborahswanson.net
Fri Dec 30 19:48:16 EST 2016


> On 30/12/16 23:00, Deborah Swanson wrote:
> > Oops, indentation was messed up when I copied it into the email. 
> > Should be this:
> >
> > 		if len(l1[st]) == 0:
> >                 if len(l2[st]) > 0:
> >                     l1[st] = l2[st]
> >             elif len(l2[st]) == 0:
> >                 if len(l1[st]) > 0:
> >                     l2[st] = l1[st]
> 
> That's even worse!
> 
> Anyway, ignoring all that, if what you are trying to do is 
> just do some 
> action based on a set of fixed comparisons that are known at 
> the top of 
> the function (and do not mutate depending on the path through the 
> function), then you can just cache the comparisons and then 
> compare the 
> resulting set of boolean results (note that my examples are 
> NOT based on 
> your use-case, it's just pseudo-code which happens to use 
> your expressions):
> 
> state = (len(l1[st]) == 0, len(l2[st]) > 0)
> if state == (True, False):
>    pass
> elif state == (False, True):
>    pass
> 
> ... etc.
> 
> If the len() comparisons are tri-state (i.e., in some cases 
> you want to 
> know if the length is <, ==, or > 0, depending on one of the other 
> comparisons) then you can do something like:
> 
> def clamp(foo):
>    return min(max(-1, foo), 1)
> 
> state = (clamp(cmp(len(l1[st]), 0), cmp(len(l2[st]), 0))
> if state == (0, -1):
>    pass
> elif state == (1, -1):
>    pass
> 
> ... etc.
> 
> I'm not sure this makes it much more readable though - but if 
> you make 
> the RHS of those comparisons a symbolic name you might be getting 
> somewhere -
> 
> ACTION1 = (0, -1)
> ACTION2 = (1, -1)
> if state == ACTION1:
>    pass
> elif state == ACTION2:
>    pass
> 
> Hope that helps, E.
> 

Thanks Erik, I really like your method of capturing the state and then
reusing it. I'm sure I can use it in other situations. In this case,
since I now have it down to:

if not len(l1[st]) and len(l2[st]):
		l1[st] = l2[st]
elif not len(l2[st]) and len(l1[st]):
		l2[st] = l1[st]

I'm not sure caching the state really simplifies that much, although I'm
going to play around with caching the state of all four fields for both
rows, or maybe for all rows to be compared. The code I've been posting
is only for one field and 2 rows, but there are 4 fields to be compared
and there can be up to 10 rows (or more) that are identical except for
the date. Would be nifty to do them all in one swipe. 

It's possible that there are some efficiencies to be found in treating
the 4 field comparisons as one problem. Or maybe I should write a little
function, since the only thing that changes in the comparisons for a set
of rows is the 4 fields. I'm going to try that now, and quite possibly
caching the state would really be useful in that function. Just gobble
them all up in one bite!



More information about the Python-list mailing list