views:

146

answers:

4

I'd like to know what is getting assigned to what in line 8.

# Iterators

class Fibs:
    def __init__(self):
        self.a = 0
        self.b = 1
    def next(self):
        self.a, self.b = self.b, self.a+self.b # <--- here
        return self.a
    def __iter__(self):
        return self

fibs = Fibs()

for f in fibs:
    if f > 1000:
        print f
        break

The rest of the program I really don't need much explanation. I'm not sure what's getting assigned to what.

+7  A: 

It's a pair assignment, a shorthand of

t = self.a
self.a = self.b
self.b = t+self.b

just to use an one-liner instead that two assignments.. to be precise i think that the left operand of the assignment is considered a tuple of two elements, so you are like assigning to tuple (self.a, self,b) the value (self.b, self.a+self.b) which does the same thing as the three separate assignments written before without the need of a temporary variable. This because, while without using tuple the assignments are executed sequentially, in your example they are resolved at the same time, preserving the value of self.a in second assignment.

As stated in documentation:

Assignment of an object to a target list is recursively defined as follows.

  • If the target list is a single target: The object is assigned to that target.
  • If the target list is a comma-separated list of targets (your case): The object must be an iterable with the same number of items as there are targets in the target list, and the items are assigned, from left to right, to the corresponding targets. (This rule is relaxed as of Python 1.5; in earlier versions, the object had to be a tuple. Since strings are sequences, an assignment like a, b = "xy" is now legal as long as the string has the right length.)
Jack
Simple enough then. Thanks for clarifying.
jimmyc3po
This would result in `self.b` being multiplied by 2, instead of being the sum of the two variables.
Jesse Dhillon
Correct. If the 2 lines were executed in sequence, the wrong thing would happen. I explained this briefly in my answer and Mark Byers in more detail in his.
Carl Smotricz
Thank you for the in-depth explanation on this. All of your answers helped. But because you gave such a good and detailed explanation I'd like to see if you would answer one other question about this program. :) The program that I pasted at http://paste.pocoo.org/show/238815/ couldn't I have just as easily on Line 9 put 'return self.b' instead of the 'return self.a' and it would still be the same "valid" program. It still outputs the same 1597 and I think (and I might be mistaken) it'll be one less iteration as well? Regardless though, 'return self.b' on Line 9 is just as valid right?
jimmyc3po
@Jesse: you are right, my fault of a quick explaination :)
Jack
+3  A: 

Without looking at the surrounding code, I'd say it's the heart of an algorithm for computing Fibonacci numbers.

It translates to the equivalent of:

a = b
b = a + b

...thereby computing the next number(s) in the sequence.

If you look at a sequence of numbers like

1 1 2 3 5 8 13 21 ...

and you let a and b be the last two numbers, then afterwards you'll have the next number in b and the former last number (b) in a.

The reason to use that strange notation is so as to accomplish both assignments at the same time. If they were done sequentially as in the 2 lines above, the value of a would be clobbered in the first line and you'd just be doubling b in the 2nd line.

Carl Smotricz
+8  A: 

It's a multiple assignment roughly equivalent to this:

tmp = self.a
self.a = self.b
self.b = tmp + self.b

Or this pseudo-code:

a' = b
b' = a + b

As you can see the multiple assignment is much more concise than separate assignments and more closely resembles the pseudo-code example.

Almost that example is given in the Python documentation as an example of calculating Fibonacci numbers. One of the advantages of the multiple assignment is that the variables on the right hand side are evaluated before any of the assignments take place, saving the need for the temporary variable in this case.

Mark Byers
First, I'd like to thank you for pointing me to the Python documentation link. This lead me to just the place I needed to truly understand how the Fibonacci numbers were being "looped"and printed out. I now see the how it's done and I'm much better for it. Also, I'm not sure if I can up vote all three of you. If I can't, it's a shame because you all deserve it, I'm going to try...etc...
jimmyc3po
I asked another question concerning this program t Jack but if you have the time it would be great to get more than one response. If you have the time. Thanks again for earlier explanation.
jimmyc3po
Couldn't I have just as easily on Line 9 put 'return self.b' instead of the 'return self.a' and it would still be the same "valid" program? It outputs the same number, just curious that's all.
jimmyc3po
+1  A: 

Be aware that a paired assignment is not a "special feature" of Python. If you know a bit about Python, it's something you already know about but you may not know you know. When you put the following into the python console:

>>> 'a', 'b'

What you get in return is:

('a', 'b')

In other words, a tuple. In your example,

self.a, self.b = self.b, self.a+self.b

what you're really doing is:

(self.a, self.b) = (self.b, self.a+self.b)
  1. Create a tuple that contains the value of self.b and the value of self.a+self.b. (The tuple on the right.)
  2. Create a tuple that contains self.a and self.b. (The left-hand tuple.)
  3. In order to create that left-hand tuple, create a new instance of self.a and self.b for that new tuple. Their old values don't matter anymore: they're in the temporary right-hand tuple.
  4. Assign value 0 of the left tuple variable to value 0 of the right tuple.
  5. Assign value 1 of the left tuple variable to value 1 of the right tuple.
  6. Now that both variables of the left tuple are assigned, delete both tuples. The new variables remain with their new values.

So, for example, you can do:

>>> a, b = 1, 2
>>> a, b
(1, 2)
>>> a, b = b, a
>>> a, b
(2, 1)

There are still temporary variables involved under the hood, but you, the programmer, don't have to deal with them.

eje211
I'm not sure where you getting your ideas, but you probably would want to learn more about Python variables.
SilentGhost
If what I wrote is wrong, I will remove it. Are you saying it is wrong?
eje211