Cleaning up conditionals

Deborah Swanson python at deborahswanson.net
Fri Dec 30 22:59:58 EST 2016


> On 2016-12-31 00:48, Deborah Swanson wrote:
> >> 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]
> >
> [snip]
> 
> An empty list is considered falsey and a non-empty list is 
> considered truey:
> 
>  >>> bool([])
> False
>  >>> bool([0])
> True
> 
> You don't care what the list's length is, only whether it's 0 
> or not, so:
> 
> if not l1[st] and l2[st]:
>      l1[st] = l2[st]
> elif not l2[st] and l1[st]:
>      l2[st] = l1[st]
> 

Similar, actually the same as Cameron suggested. I really need to
revisit testing for empty. I probably rejected it early on for some bad
reason (you don't understand everything that goes wrong when you're
learning).




More information about the Python-list mailing list