simultaneous assignment

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

    simultaneous assignment

    Is there a way to assign multiple variables to the same value, but so
    that an identity test still evaluates to False?

    e.g.:
    [color=blue][color=green][color=darkred]
    >>> w = x = y = z = False
    >>> w[/color][/color][/color]
    False[color=blue][color=green][color=darkred]
    >>> x[/color][/color][/color]
    False[color=blue][color=green][color=darkred]
    >>> w == x[/color][/color][/color]
    True[color=blue][color=green][color=darkred]
    >>> w is x[/color][/color][/color]
    True # not sure if this is harmful

    The first line above is the only way I know to do it, but it seems to
    necessarily lead to the true identity test.
  • Diez B. Roggisch

    #2
    Re: simultaneous assignment

    John Salerno wrote:
    [color=blue]
    > Is there a way to assign multiple variables to the same value, but so
    > that an identity test still evaluates to False?
    >
    > e.g.:
    >[color=green][color=darkred]
    > >>> w = x = y = z = False
    > >>> w[/color][/color]
    > False[color=green][color=darkred]
    > >>> x[/color][/color]
    > False[color=green][color=darkred]
    > >>> w == x[/color][/color]
    > True[color=green][color=darkred]
    > >>> w is x[/color][/color]
    > True # not sure if this is harmful
    >
    > The first line above is the only way I know to do it, but it seems to
    > necessarily lead to the true identity test.[/color]

    Yes, and there is no way around that - given that python has not an
    overloadable assignment operator as e.g. C++ offers (praise the BDFL!). The
    semantics of what looks like assignment in python is "I've got a fancy
    object somewhere, and now I want to be able to refer to it by that nice
    name here". Actually things are somewhat more complicated in case of
    list/dictionary element assignment, but for your case that is irrelevant.

    Besides, depending on what you assign (e.g. integers, as well as the boolean
    constants I guess) you might not even have the choice to guarantee how the
    identity test results anyway. Consider this:
    [color=blue][color=green][color=darkred]
    >>> a = 1000000
    >>> b = 1000000
    >>> a is b[/color][/color][/color]
    False[color=blue][color=green][color=darkred]
    >>> a = 100
    >>> b = 100
    >>> a is b[/color][/color][/color]
    False[color=blue][color=green][color=darkred]
    >>> a = 10
    >>> b = 10
    >>> a is b[/color][/color][/color]
    True[color=blue][color=green][color=darkred]
    >>>[/color][/color][/color]

    I can't imagine what you're actually after here, but assuming that you
    really need this and that we're talking "real" objects here, sequence
    unpacking and assignment might come handy here, together with a small
    list-comp:

    a, b, c = [copy.copy(o) for i in xrange(3)]


    Diez

    Comment

    • Boris Borcic

      #3
      Re: simultaneous assignment

      John Salerno wrote:[color=blue]
      > Is there a way to assign multiple variables to the same value, but so
      > that an identity test still evaluates to False?
      >
      > e.g.:
      >[color=green][color=darkred]
      > >>> w = x = y = z = False
      > >>> w[/color][/color]
      > False[color=green][color=darkred]
      > >>> x[/color][/color]
      > False[color=green][color=darkred]
      > >>> w == x[/color][/color]
      > True[color=green][color=darkred]
      > >>> w is x[/color][/color]
      > True # not sure if this is harmful
      >
      > The first line above is the only way I know to do it, but it seems to
      > necessarily lead to the true identity test.[/color]
      [color=blue][color=green][color=darkred]
      >>> class Foo :[/color][/color][/color]
      def __eq__(*blah) : return False

      [color=blue][color=green][color=darkred]
      >>> w = x = y = z = Foo()
      >>> w == x[/color][/color][/color]
      False[color=blue][color=green][color=darkred]
      >>> w is x[/color][/color][/color]
      True[color=blue][color=green][color=darkred]
      >>>[/color][/color][/color]

      Comment

      • John Salerno

        #4
        Re: simultaneous assignment

        Boris Borcic wrote:
        [color=blue][color=green][color=darkred]
        > >>> w == x[/color][/color]
        > False[color=green][color=darkred]
        > >>> w is x[/color][/color]
        > True[color=green][color=darkred]
        > >>>[/color][/color][/color]

        That's the opposite of what I want to happen.

        Comment

        • John Salerno

          #5
          Re: simultaneous assignment

          Diez B. Roggisch wrote:
          [color=blue]
          > I can't imagine what you're actually after here, but assuming that you
          > really need this[/color]

          Hard to explain because I'm still trying to figure out how to do it
          myself. I'm trying to solve a little puzzle using Python, even though
          I'm sure it's not necessary. Basically W, X, Y and Z are propositions
          that are either true or false, and the puzzle lists a few statements
          such as "Exactly one of X, Y and Z is true", and I'm trying to work out
          a little algorithm that might test for this kind of stuff.

          Another thing I'm trying to do is write a function that tests to see if
          a list contains exactly one true item, and the rest are false (obviously
          this would have to be a list of boolean values, I guess). I'm sure this
          isn't a handy utility, but I enjoy figuring out how to implement it.

          Comment

          • Diez B. Roggisch

            #6
            Re: simultaneous assignment

            John Salerno wrote:
            [color=blue]
            > Diez B. Roggisch wrote:
            >[color=green]
            >> I can't imagine what you're actually after here, but assuming that you
            >> really need this[/color]
            >
            > Hard to explain because I'm still trying to figure out how to do it
            > myself. I'm trying to solve a little puzzle using Python, even though
            > I'm sure it's not necessary. Basically W, X, Y and Z are propositions
            > that are either true or false, and the puzzle lists a few statements
            > such as "Exactly one of X, Y and Z is true", and I'm trying to work out
            > a little algorithm that might test for this kind of stuff.[/color]

            Then use a Proposition-class that holds the actual value.
            [color=blue]
            > Another thing I'm trying to do is write a function that tests to see if
            > a list contains exactly one true item, and the rest are false (obviously
            > this would have to be a list of boolean values, I guess).[/color]

            No - you can for example override the comparison-semantics on the
            Proposition-class to be comparable with True/False with the proper
            semantics:




            class Proposition(obj ect):

            def __init__(self, v):
            self._v = v


            def __eq__(self, o):
            return self._v == o


            TrueProposition = Proposition(Tru e)
            FalsePropositio n = Proposition(Fal se)

            print True == TrueProposition
            print False == TrueProposition
            print False == FalsePropositio n



            Diez

            Comment

            • John Salerno

              #7
              Re: simultaneous assignment

              Diez B. Roggisch wrote:
              [color=blue]
              > Then use a Proposition-class that holds the actual value.
              >[color=green]
              >> Another thing I'm trying to do is write a function that tests to see if
              >> a list contains exactly one true item, and the rest are false (obviously
              >> this would have to be a list of boolean values, I guess).[/color]
              >
              > No - you can for example override the comparison-semantics on the
              > Proposition-class to be comparable with True/False with the proper
              > semantics:[/color]

              Hmm, classes still scare me a little, but I should consider this. The
              only thing is, it is not known in advance if the propositions are true
              or false, you have to figure that out yourself based on the combination
              of the statements given. I don't know if this changes the idea behind
              your Proposition class...I'll have to give it some more thought.

              Comment

              • David Isaac

                #8
                Re: simultaneous assignment


                "John Salerno" <johnjsal@NOSPA Mgmail.com> wrote in message
                news:8dM5g.2031 $No6.43874@news .tufts.edu...[color=blue]
                > Is there a way to assign multiple variables to the same value, but so
                > that an identity test still evaluates to False?[/color]

                Make sure the value is not a singleton.
                Assign them one at a time.[color=blue][color=green][color=darkred]
                >>> w=1000
                >>> x=1000
                >>> w==x[/color][/color][/color]
                True[color=blue][color=green][color=darkred]
                >>> w is x[/color][/color][/color]
                False[color=blue][color=green][color=darkred]
                >>> w=2
                >>> x=2
                >>> w==x[/color][/color][/color]
                True[color=blue][color=green][color=darkred]
                >>> w is x[/color][/color][/color]
                True

                Hope that helps,
                Alan Isaac


                Comment

                • Diez B. Roggisch

                  #9
                  Re: simultaneous assignment

                  > Hmm, classes still scare me a little, but I should consider this. The[color=blue]
                  > only thing is, it is not known in advance if the propositions are true
                  > or false, you have to figure that out yourself based on the combination
                  > of the statements given. I don't know if this changes the idea behind
                  > your Proposition class...I'll have to give it some more thought.[/color]

                  No, that was just an example to illustrate the comparison semantics. I don't
                  know enough about your problem to model it more appropriately.

                  Besides, you can of course change that self._v of a proposition.

                  Diez

                  Comment

                  • bruno at modulix

                    #10
                    Re: simultaneous assignment

                    John Salerno wrote:[color=blue]
                    > Is there a way to assign multiple variables to the same value,
                    > but so
                    > that an identity test still evaluates to False?[/color]

                    re-phrase it according to how Python works, and you'll get the answer:

                    "Is there a way to bind multiple names to the same object, but so the
                    identity of this object is different from the identity of this object ?"
                    [color=blue]
                    > e.g.:
                    >[color=green][color=darkred]
                    >>>> w = x = y = z = False[/color][/color][/color]

                    the statement:
                    a = False
                    doesn't mean "assign the value False to the variable a", but "make the
                    name 'a' reference the object False" - which is quite different.
                    [color=blue][color=green][color=darkred]
                    >>> a = False
                    >>> b = False
                    >>> a is b[/color][/color][/color]
                    True[color=blue][color=green][color=darkred]
                    >>> id(False)[/color][/color][/color]
                    46912499309888[color=blue][color=green][color=darkred]
                    >>> id(a)[/color][/color][/color]
                    46912499309888[color=blue][color=green][color=darkred]
                    >>> id(b)[/color][/color][/color]
                    46912499309888[color=blue][color=green][color=darkred]
                    >>>[/color][/color][/color]

                    [color=blue][color=green][color=darkred]
                    >>>> w[/color][/color]
                    > False[color=green][color=darkred]
                    >>>> x[/color][/color]
                    > False[color=green][color=darkred]
                    >>>> w == x[/color][/color]
                    > True[color=green][color=darkred]
                    >>>> w is x[/color][/color]
                    > True # not sure if this is harmful[/color]

                    Using identity test for boolean tests is usually not a good idea since
                    many other objects evals to True or False in a boolean context while not
                    being neither the True nor the False objects.
                    [color=blue]
                    > The first line above is the only way I know to do it, but it seems to
                    > necessarily lead to the true identity test.[/color]

                    It does.

                    Now if I may ask: what is your actual problem ?

                    --
                    bruno desthuilliers
                    python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
                    p in 'onurb@xiludom. gro'.split('@')])"

                    Comment

                    • bruno at modulix

                      #11
                      Re: simultaneous assignment

                      John Salerno wrote:[color=blue]
                      > Boris Borcic wrote:
                      >[color=green][color=darkred]
                      >> >>> w == x[/color]
                      >> False[color=darkred]
                      >> >>> w is x[/color]
                      >> True[color=darkred]
                      >> >>>[/color][/color]
                      >
                      >
                      > That's the opposite of what I want to happen.[/color]

                      And that wouldn't be really helpful anyway !-)

                      --
                      bruno desthuilliers
                      python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
                      p in 'onurb@xiludom. gro'.split('@')])"

                      Comment

                      • John Salerno

                        #12
                        Re: simultaneous assignment

                        bruno at modulix wrote:
                        [color=blue]
                        > Now if I may ask: what is your actual problem ?[/color]

                        Ok, since you're so curious. :)

                        Here's a scan of the page from the puzzle book:


                        Basically I'm reading this book to give me little things to try out in
                        Python. There's no guarantee that this puzzle is even conducive to (or
                        worthy of) a programming solution.

                        Comment

                        • Steve R. Hastings

                          #13
                          Re: simultaneous assignment

                          On Tue, 02 May 2006 17:15:05 +0000, John Salerno wrote:[color=blue]
                          > Basically W, X, Y and Z are propositions
                          > that are either true or false, and the puzzle lists a few statements
                          > such as "Exactly one of X, Y and Z is true", and I'm trying to work out
                          > a little algorithm that might test for this kind of stuff.[/color]

                          Okay. You don't need to worry about the "is" tests at all.


                          Python always represents the value "True" with a reference to a True
                          object, and likewise "False" is a reference to a False object. To save
                          memory, Python has just one of each object, so:

                          a = False
                          b = False
                          a is b # this will always be true


                          As some other posters showed by example, but didn't really explain, Python
                          will *sometimes* but not always reuse integer objects. For common integer
                          values such as 0 and 1, Python will reuse the objects; for uncommon
                          (larger) values, Python usually won't. So:

                          a = 12345
                          b = 12345
                          a is b # probably not true
                          a = 0
                          b = 0
                          a is b # always true


                          A key point is that you never really "assign a value to a variable". What
                          you really do is "bind an object reference to a name". The long,
                          simultaneous assignment form binds the same object reference to multiple
                          variables:

                          a = b = c = d = 12345
                          a is b # always true


                          But as soon as you reassign any of the variables you will rebind the name
                          to some other object reference:

                          a += 1
                          a is b # definitely false
                          a = 12345
                          a is b # probably false


                          Python *could* notice that it already has an integer object with the value
                          12345, and rebind the name a with a reference to it. But in practice
                          Python will probably just create a new integer object with value 12345,
                          since the Python interpreter doesn't spend large amounts of time looking
                          through its collection of objects to find ones that can be reused.

                          Python also has exactly one "None" object, and always uses references to
                          it whenever you reference None in your code. This is why it is preferred
                          Python style to test for None with an "is" test:

                          a is None


                          Anyway, the major point I want you to take away from all this: it doesn't
                          matter whether the "is" test succeeds or fails, if all you care about is
                          the *value* of a variable. Python reuses object references to save
                          memory, because this doesn't affect expressions that only care about the
                          *value*. Your logic tests only care about True vs. False; they don't care
                          about the underlying implementation of how True and False are expressed.

                          [color=blue]
                          > Another thing I'm trying to do is write a function that tests to see if
                          > a list contains exactly one true item, and the rest are false (obviously
                          > this would have to be a list of boolean values, I guess). I'm sure this
                          > isn't a handy utility, but I enjoy figuring out how to implement it.[/color]

                          This is a simple problem. I suggest you loop over the list and simply
                          count how many values are false, and how many are true. I just wrote and
                          tested this function in about a minute.

                          The list doesn't have to be a list of booleans, actually. Python has a
                          set of rules for evaluating other values as booleans:

                          if 0:
                          pass # never executed; 0 always false

                          if "":
                          pass # never executed; 0-length string always false

                          if []:
                          pass # never executed; 0-length list always false


                          So, don't test to see if something is equal to True or False:

                          if 0 == False:
                          pass # never executed; False and 0 do not directly compare


                          You *could* do this, but I don't really recommend it:

                          if bool(0) == False:
                          pass # always executed


                          Do this:

                          if not 0:
                          pass # always executed

                          if 1:
                          pass # always executed


                          To convert a random value into a boolean value, you could use either
                          "bool()" or you could use "not not":

                          a = not not 0
                          b = bool(0)


                          "not not" will work on older versions of Python that didn't have an
                          explicit boolean type; "not 0" would return 1 in that case. "bool()"
                          will work in Python 2.2 and newer.
                          --
                          Steve R. Hastings "Vita est"
                          steve@hastings. org http://www.blarg.net/~steveha

                          Comment

                          • John Salerno

                            #14
                            Re: simultaneous assignment

                            Steve R. Hastings wrote:
                            [color=blue]
                            > Anyway, the major point I want you to take away from all this: it doesn't
                            > matter whether the "is" test succeeds or fails, if all you care about is
                            > the *value* of a variable. Python reuses object references to save
                            > memory, because this doesn't affect expressions that only care about the
                            > *value*. Your logic tests only care about True vs. False; they don't care
                            > about the underlying implementation of how True and False are expressed.[/color]

                            Great explanation. Thanks!
                            [color=blue]
                            > This is a simple problem. I suggest you loop over the list and simply
                            > count how many values are false, and how many are true. I just wrote and
                            > tested this function in about a minute.[/color]

                            Yeah, after trying some crazy things, I just wrote it this way:

                            def truth_test(seq) :
                            truth = 0
                            for item in seq:
                            if item:
                            truth += 1
                            if truth == 1:
                            return True
                            else:
                            return False

                            Not sure I like having to keep a counter though, but the other stuff I
                            did was really convoluted, like checking to see if the first item was
                            True, and if it was, popping it from the list and iterating over the
                            rest of the items (needless to say, the in-place change wasn't helpful).

                            Comment

                            • Grant Edwards

                              #15
                              Re: simultaneous assignment

                              On 2006-05-02, John Salerno <johnjsal@NOSPA Mgmail.com> wrote:
                              [color=blue]
                              > Yeah, after trying some crazy things, I just wrote it this way:
                              >
                              > def truth_test(seq) :
                              > truth = 0
                              > for item in seq:
                              > if item:
                              > truth += 1
                              > if truth == 1:
                              > return True
                              > else:
                              > return False
                              >
                              > Not sure I like having to keep a counter though, but the other stuff I
                              > did was really convoluted, like checking to see if the first item was
                              > True, and if it was, popping it from the list and iterating over the
                              > rest of the items (needless to say, the in-place change wasn't helpful).[/color]

                              Python knows how to count. :)

                              def countFalse(seq) :
                              return len([v for v in seq if not v])

                              def countTrue(seq):
                              return len([v for v in seq if v])

                              def truth_test(seq) :
                              return countTrue(seq) == 1

                              --
                              Grant Edwards grante Yow! I FORGOT to do the
                              at DISHES!!
                              visi.com

                              Comment

                              Working...