builtin functions for and and or?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Roose

    #1

    builtin functions for and and or?

    I need this a lot: a one line way to do a n-ary and or 'or'.

    e.g.,

    result = True
    for x in L:
    if not boolean_functio n(x):
    result = False

    or
    [color=blue][color=green][color=darkred]
    >>> reduce(operator .__and__, [boolean_functio n(x) for x in L)[/color][/color][/color]

    So usually I just write a little function any( L, boolean_functio n =
    identity ) or all( ... ). But I am kind of sick of doing that all the
    time -- does it exist anywhere in the Python libraries? It seems really
    common to me.

    The first way isn't satisfactory because it takes so many lines for what is
    essentially one "primitive" operation. The second way isn't great because
    it is not as readable and many readers don't like to see reduce, even if it
    is a common idiom like that. Also I don't believe it short circuits.





  • Diez B. Roggisch

    #2
    Re: builtin functions for and and or?

    > So usually I just write a little function any( L, boolean_functio n =[color=blue]
    > identity ) or all( ... ). But I am kind of sick of doing that all the
    > time -- does it exist anywhere in the Python libraries? It seems really
    > common to me.[/color]

    Put things into your own module and add it to your python path. Then you
    only have to write it once.
    [color=blue]
    > The first way isn't satisfactory because it takes so many lines for what
    > is
    > essentially one "primitive" operation. The second way isn't great because
    > it is not as readable and many readers don't like to see reduce, even if
    > it
    > is a common idiom like that. Also I don't believe it short circuits.[/color]

    It doesn't but so doesn't your loop example. Put a break in there once
    Result is False.

    --
    Regards,

    Diez B. Roggisch

    Comment

    • Michael Hartl

      #3
      Re: builtin functions for and and or?

      I warmly recommend downloading Peter Norvig's Python utilities file
      (http://aima.cs.berkeley.edu/python/utils.py) and putting it on your
      Python path. (E.g., in bash, put a line like

      export PYTHONPATH="/path/to/utilities_direc tory"

      in your .bashrc file.) The utils.py file defines many useful
      functions, including the ones you want:

      # def every(predicate , seq):
      # """True if every element of seq satisfies predicate.
      # Ex: every(callable, [min, max]) ==> 1; every(callable, [min, 3])
      ==> 0
      # """
      # for x in seq:
      # if not predicate(x): return False
      # return True
      #
      # def some(predicate, seq):
      # """If some element x of seq satisfies predicate(x), return
      predicate(x).
      # Ex: some(callable, [min, 3]) ==> 1; some(callable, [2, 3]) ==> 0
      # """
      # for x in seq:
      # px = predicate(x)
      # if px: return px
      # return False

      Michael

      --
      Michael D. Hartl, Ph.D.
      Chief Technology Officer
      Hangzhou Quark Sports Goods Co., Ltd: Find professional pickleball paddle, padel racket, popular pickleball paddle, high spin pickleball paddle manufacturers in China here! Please feel free to wholesale high quality sports goods at competitive price from our factory. Contact us for custom service and OEM service.


      Comment

      • Brian Beck

        #4
        Re: builtin functions for and and or?

        Roose wrote:[color=blue]
        > I need this a lot: a one line way to do a n-ary and or 'or'.[/color]

        Looks like there are itertools recipes for those, similar to what
        Michael just posted. Taken from here:


        def all(seq, pred=bool):
        "Returns True if pred(x) is True for every element in the iterable"
        for elem in ifilterfalse(pr ed, seq):
        return False
        return True

        def any(seq, pred=bool):
        "Returns True if pred(x) is True for at least one element in the
        iterable"
        for elem in ifilter(pred, seq):
        return True
        return False


        --
        Brian Beck
        Adventurer of the First Order

        Comment

        • Steven Bethard

          #5
          Re: builtin functions for and and or?

          Roose wrote:[color=blue]
          > I need this a lot: a one line way to do a n-ary and or 'or'.
          >
          > e.g.,
          >
          > result = True
          > for x in L:
          > if not boolean_functio n(x):
          > result = False
          >
          > or
          >[color=green][color=darkred]
          >>>>reduce(oper ator.__and__, [boolean_functio n(x) for x in L)[/color][/color][/color]

          Can you use itertools?

          py> def boolfn(x):
          .... print "boolfn: %r" % x
          .... return bool(x)
          ....
          py> True in itertools.imap( boolfn, ['a', '', 'b'])
          boolfn: 'a'
          True
          py> True in itertools.imap( boolfn, ['', '', ''])
          boolfn: ''
          boolfn: ''
          boolfn: ''
          False
          py> False in itertools.imap( boolfn, ['a', '', 'b'])
          boolfn: 'a'
          boolfn: ''
          True
          py> False in itertools.imap( boolfn, ['a', 'a', 'b'])
          boolfn: 'a'
          boolfn: 'a'
          boolfn: 'b'
          False

          It even shortcircuits when appropriate.

          Steve

          Comment

          • Brian Beck

            #6
            Re: builtin functions for and and or?

            Brian Beck wrote:[color=blue]
            > def all(seq, pred=bool):
            > "Returns True if pred(x) is True for every element in the iterable"
            > for elem in ifilterfalse(pr ed, seq):
            > return False
            > return True
            >
            > def any(seq, pred=bool):
            > "Returns True if pred(x) is True for at least one element in the
            > iterable"
            > for elem in ifilter(pred, seq):
            > return True
            > return False[/color]

            I should probably note, you'll have to

            from itertools import ifilter, ifilterfalse

            to use these.

            --
            Brian Beck
            Adventurer of the First Order

            Comment

            • Brian Beck

              #7
              Re: builtin functions for and and or?

              Roose wrote:[color=blue]
              > I need this a lot: a one line way to do a n-ary and or 'or'.[/color]

              Here's a one-liner for the n-ary and:

              bool(min(bool(x ) for x in L))


              py> bool(min(bool(x ) for x in [1, 1, 1, 0]))
              False
              py> bool(min(bool(x ) for x in [1, 1, 1, 1]))
              True
              py> bool(min(bool(x ) for x in ['a', '', 'b', 'c']))
              False
              py> bool(min(bool(x ) for x in ['a', 'b', 'c', 'd']))
              True

              --
              Brian Beck
              Adventurer of the First Order

              Comment

              • Steven Bethard

                #8
                Re: builtin functions for and and or?

                Brian Beck wrote:[color=blue]
                > Roose wrote:
                >[color=green]
                >> I need this a lot: a one line way to do a n-ary and or 'or'.[/color]
                >
                > Here's a one-liner for the n-ary and:
                >
                > bool(min(bool(x ) for x in L))
                >
                > py> bool(min(bool(x ) for x in [1, 1, 1, 0]))
                > False
                > py> bool(min(bool(x ) for x in [1, 1, 1, 1]))
                > True
                > py> bool(min(bool(x ) for x in ['a', '', 'b', 'c']))
                > False
                > py> bool(min(bool(x ) for x in ['a', 'b', 'c', 'd']))
                > True[/color]

                Another alternative:

                not False in (bool(x) for x in L)

                py> not False in (bool(x) for x in [1, 1, 1, 0])
                False
                py> not False in (bool(x) for x in [1, 1, 1, 1])
                True
                py> not False in (bool(x) for x in ['a', '', 'b', 'c'])
                False
                py> not False in (bool(x) for x in ['a', 'b', 'c', 'd'])
                True

                Note that this should short-circuit, where min won't.

                Steve

                Comment

                • John Machin

                  #9
                  Re: builtin functions for and and or?


                  Michael Hartl wrote:[color=blue]
                  > I warmly recommend downloading Peter Norvig's Python utilities file
                  > (http://aima.cs.berkeley.edu/python/utils.py) and putting it on your
                  > Python path. (E.g., in bash, put a line like
                  >
                  > export PYTHONPATH="/path/to/utilities_direc tory"
                  >
                  > in your .bashrc file.) The utils.py file defines many useful
                  > functions, including the ones you want:
                  >
                  > # def every(predicate , seq):
                  > # """True if every element of seq satisfies predicate.
                  > # Ex: every(callable, [min, max]) ==> 1; every(callable, [min,[/color]
                  3])[color=blue]
                  > ==> 0
                  > # """
                  > # for x in seq:
                  > # if not predicate(x): return False
                  > # return True
                  > #
                  > # def some(predicate, seq):
                  > # """If some element x of seq satisfies predicate(x), return
                  > predicate(x).
                  > # Ex: some(callable, [min, 3]) ==> 1; some(callable, [2, 3]) ==>[/color]
                  0[color=blue]
                  > # """
                  > # for x in seq:
                  > # px = predicate(x)
                  > # if px: return px
                  > # return False
                  >[/color]

                  What an interesting mixed API design. The every() function returns True
                  or False. However the "some" function returns the FIRST fat result if
                  it's true in the non-boolean sense, otherwise False.

                  Looks like there could theoretically be scope for two pairs of
                  functions, one returning strictly True/False, and the other pair
                  emulating chains of Python 'and's and 'or's.

                  I.e.
                  False or 0 or [] evaluates to []
                  0 or 5 or 6 evaluates to 5
                  42 and None and True evaluates to None
                  4 and 5 and 6 evaluates to 6

                  All very nice, but useful? Dubious. PEPpable? Nah, two thumbs down.

                  Diez's advice to the OP is sound: if it bothers you that much, mine the
                  net for, or write, routines that do exactly what you want, and put them
                  in your own utilities module.

                  Comment

                  • Brian Beck

                    #10
                    Re: builtin functions for and and or?

                    Steven Bethard wrote:[color=blue]
                    > Another alternative:
                    >
                    > not False in (bool(x) for x in L)
                    >
                    > Note that this should short-circuit, where min won't.
                    >
                    > Steve[/color]

                    Whoops, for some reason the thought that short-circuiting didn't apply
                    to And entered my mind while trying to post a nice solution. Hard to say
                    why considering I have to do stuff like this on a daily basis!

                    Ignore mine except as a novelty, then.

                    --
                    Brian Beck
                    Adventurer of the First Order

                    Comment

                    • George Sakkis

                      #11
                      Re: builtin functions for and and or?

                      "Roose" <b@b.b> wrote in message news:y9PPd.4645 $ZZ.528@newssvr 23.news.prodigy .net...[color=blue]
                      > I need this a lot: a one line way to do a n-ary and or 'or'.
                      >
                      > e.g.,
                      >
                      > result = True
                      > for x in L:
                      > if not boolean_functio n(x):
                      > result = False
                      >
                      > or
                      >[color=green][color=darkred]
                      > >>> reduce(operator .__and__, [boolean_functio n(x) for x in L)[/color][/color]
                      >
                      > So usually I just write a little function any( L, boolean_functio n =
                      > identity ) or all( ... ). But I am kind of sick of doing that all the
                      > time -- does it exist anywhere in the Python libraries? It seems really
                      > common to me.
                      >
                      > The first way isn't satisfactory because it takes so many lines for what is
                      > essentially one "primitive" operation. The second way isn't great because
                      > it is not as readable and many readers don't like to see reduce, even if it
                      > is a common idiom like that. Also I don't believe it short circuits.[/color]


                      You're right, it doesn't short circuit, as most of the examples posted above. Here's one that it
                      does:

                      from itertools import ifilter, dropwhile

                      def any(pred, iterable):
                      try: ifilter(pred,it erable).next()
                      except StopIteration: return False
                      else: return True

                      def all(pred, iterable):
                      try: dropwhile(pred, iterable).next( )
                      except StopIteration: return True
                      else: return False


                      George


                      Comment

                      • bearophileHUGS@lycos.com

                        #12
                        Re: builtin functions for and and or?

                        In Python there are so many ways to do things...
                        This looks like another one, I haven't tested it:

                        not False in imap(pred, iterable)

                        As usual tests are required to measure the faster one.
                        I agree with Roose, there are are some "primitive" operations (like
                        this, and flatten, partition, mass removal of keys from a dictionary,
                        and few others) that can be added to the language (but I'm still not
                        capabable of doing it myself, and Python is free, so it's not right to
                        ask people to work for free for us).

                        Bear hugs,
                        Bearophile

                        Comment

                        • Brian Beck

                          #13
                          Re: builtin functions for and and or?

                          George Sakkis wrote:[color=blue]
                          > You're right, it doesn't short circuit, as most of the examples posted above. Here's one that it
                          > does:
                          >
                          > ...[/color]

                          I also looked into taking advantage of itertools' dropwhile, but the all
                          and any recipes included in the itertools documentation do short-circuit
                          and don't require the setup of a try/except/else.

                          --
                          Brian Beck
                          Adventurer of the First Order

                          Comment

                          • Roose

                            #14
                            Re: builtin functions for and and or?


                            "Diez B. Roggisch" <deetsNOSPAM@we b.de> wrote in message
                            news:cuofcj$jvt $02$1@news.t-online.com...[color=blue][color=green]
                            > > So usually I just write a little function any( L, boolean_functio n =
                            > > identity ) or all( ... ). But I am kind of sick of doing that all the
                            > > time -- does it exist anywhere in the Python libraries? It seems really
                            > > common to me.[/color]
                            >
                            > Put things into your own module and add it to your python path. Then you
                            > only have to write it once.[/color]

                            Well it's not as convenient as having it built in. The thing is I'm not
                            just writing for myself. I used it at my old job, and now I'm using it at
                            my new job. There's a requirement that the user shouldn't have to modify
                            his setup beyond installing Python to run any scripts. At my first job we
                            had one way of dealing with this. Now there is another way. And then I
                            need a way to deal with it at home with my personal stuff.

                            Also the stuff typically doesn't go under the Python dir, because that is
                            not mapped to source control. And anyway people don't like mixing in our
                            code with 3rd party code.

                            The result that the path of least resistance is just to copy in a 4 line
                            function or two into the program and be done with it, even though it goes
                            against my sense of aesthetics.

                            It would be a lot simpler if it was included in the distribution. I would
                            be willing to add it (even though it is completely trivial). I think it
                            would go fine in itertools (I would even put them as builtins, but I'm not
                            going to go there because probably not everyone uses it as often as I do).

                            What do people think? I have never done this, would I just write up a PEP?

                            [color=blue]
                            >[color=green]
                            > > The first way isn't satisfactory because it takes so many lines for what
                            > > is
                            > > essentially one "primitive" operation. The second way isn't great[/color][/color]
                            because[color=blue][color=green]
                            > > it is not as readable and many readers don't like to see reduce, even if
                            > > it
                            > > is a common idiom like that. Also I don't believe it short circuits.[/color]
                            >
                            > It doesn't but so doesn't your loop example. Put a break in there once
                            > Result is False.
                            >
                            > --
                            > Regards,
                            >
                            > Diez B. Roggisch[/color]


                            Comment

                            • Roose

                              #15
                              Re: builtin functions for and and or?

                              Yeah, as we can see there are a million ways to do it. But none of them are
                              as desirable as just having a library function to do the same thing. I'd
                              argue that since there are so many different ways, we should just collapse
                              them into one: any() and all(). That is more in keeping with the python
                              philosophy I suppose -- having one canonical way to do things. Otherwise
                              you could see any of these several ways of doing it in any program, and each
                              time you have to make sure it's doing what you think. Each of them requies
                              more examination than is justified for such a trivial operation. And this
                              definitely hurts the readability of the program.


                              <bearophileHUGS @lycos.com> wrote in message
                              news:1108335152 .338013.45530@z 14g2000cwz.goog legroups.com...[color=blue]
                              > In Python there are so many ways to do things...
                              > This looks like another one, I haven't tested it:
                              >
                              > not False in imap(pred, iterable)
                              >
                              > As usual tests are required to measure the faster one.
                              > I agree with Roose, there are are some "primitive" operations (like
                              > this, and flatten, partition, mass removal of keys from a dictionary,
                              > and few others) that can be added to the language (but I'm still not
                              > capabable of doing it myself, and Python is free, so it's not right to
                              > ask people to work for free for us).
                              >
                              > Bear hugs,
                              > Bearophile
                              >[/color]


                              Comment

                              Working...