开发者

What is happening in this Python program?

开发者 https://www.devze.com 2023-01-07 23:10 出处:网络
I\'d like to know what is getting assigned to what in line 8. # Iterators class Fibs: def __init__(self):

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.


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.


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.)


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消