fengxia's profilefengxia的共享空间PhotosBlogNetwork Tools Help

Blog


    April 19

    Python Reference

    In the Python there is not pointer operation, only reference operation. The biggest difference between the pointer and the reference is that the reference is not allocated to memory and must be initialized in the definition but the pointer is on the contrary.

     

    In general, the reference is more similar to the name of the array, they are all levels of the compiler which be decided to address at compile, but in the actual process does not exist, and the pointer really exists in the memory.

     

    In the Python, the function is a kind of object which can  directly  accept the reference. For example,

     

    def a():

    pass

    For a (), there's a not a function name, but is a Variable which name is a in the current namespace, it points to a function type of object, this object is the function you want to use.

     

    In the Python Variable is a reference for value and object, python will create an object in the assignment, at the same time the newly established object will be binding with a variable name. “a = b” in the Python is not like other languages which put the value of b to a.but should be understood as: a point to the b.

     

    Objects in python could be a memory region; the reference of object can be regarded as a pointer which  points to this object.

     

    These are the three questions I come cross when I am studying Python, Thanks Brian for giving me such good explaination.

     

    > 1.  why do "a.append(1)", id(a) still equals to id(b)?

    > >>> a =[]

    > >>> b = a

    > >>> id(a)

    > 3083364108L

    > >>> id(b)

    > 3083364108L

    > >>> a.append(1)

    > >>> id(a)

    > 3083364108L

    > >>> id(b)

    > 3083364108L

    > >>> a =2

    > >>> id(a)

    > 134543188

    > >>> id(b)

    > 3083364108L

     

    This is a common source of confusion.

     

    I assume you understand what id() does.  It returns the object's memory location. This means that if the same value is returned by id for two different variable names, then the two variable names are actually referring to the same object. 

     

    Here is what is happening:

     

    b = a causes 'b' to equal 'a'.  That is, 'b' and 'a' are just variable names that are bound to the same object in memory. Therefore, when you use 'a.append(1)' the list object in that is bound to the name 'a' (and that is also pointed to by 'b') has the integer value 1 appended to it.  Nevertheless, 'a' and 'b' still are still bound to the same object in memory;  Printing 'a' or 'b' would yield the same result: [1].

     

    You will notice that after running 'a = 2', the memory location changes.  This is because 'a' is given a new value and a new memory location must be allocated to store the integer 2.  Nothing has changed for 'b', however, it is still bound to the list object in memory (so printing 'b' would still print "[1]").

     

    > 2. why the a and b turn out to be the "[1, 2, [...]]", I think it should be [1, 2, [1, 2]]

    > >>> a = []

    > >>> b = a

    > >>> a.append(1)

    > >>> a

    > [1]

    > >>> a.append(2)

    > >>> a

    > [1, 2]

    > >>> b

    > [1, 2]

    > >>> a.append(b)

    > >>> a

    > [1, 2, [...]]

    > >>> b

    > [1, 2, [...]]

     

    The explanation above should help to explain what is happening here.

    What you are seeing is a cycle in the list.  The cycle is

    represented as '[...]' when printed.  The cycle appears because 'a' and 'b' are both names that are bound to the same object in memory.Therefore, when you run a.append(b), it is the same thing as runninga.append(a), i.e., appending some object to itself.

     

    Before Python 1.5.1, Python wouldn't print '[...]', instead when you printed a list with a cycle, you would see a never-ending stream of:

     

    [1, 2, [1, 2, [1, 2, [1, 2, [1, 2, [1, 2, [1, 2, [1, 2, [1, 2,

     

    This would continue until pressing ctrl+c.

     

    > 3.: why the output is not [{'num': 1, 'sqrt': 1}, {'num': 2, 'sqrt': 4}, {'num': 3, 'sqrt': 9}]?

    > >>> a=[]

    > >>> b={'num':0,'sqrt':0}

    > >>> resurse=[1,2,3]

    > >>> for i in resurse:

    >      b['num']=i

    >      b['sqrt']=i*i

    >      a.append(b)

    > >>> a

    > [{'num': 3, 'sqrt': 9}, {'num': 3, 'sqrt': 9}, {'num': 3, 'sqrt': 9}]

     

    Here, you are experiencing a similar problem to the ones above.This problem is slightly more complicated, but the problem is fundamentally the same. 

     

    The problem is that when you run a.append(b) inside the for loop, you are appending the same object, 'b', to the 'a' list three.Therefore, each value in your 'a' list will always be the same.  If you change your for loop to:

    for i in resurse:

        b['num']=i

        b['sqrt']=i*i

        a.append(b)

        print a

     

    You will see the following results:

     

    [{'num': 1, 'sqrt': 1}]

    [{'num': 2, 'sqrt': 4}, {'num': 2, 'sqrt': 4}]

    [{'num': 3, 'sqrt': 9}, {'num': 3, 'sqrt': 9}, {'num': 3, 'sqrt':9}]

     

    Notice that each dictionary value in the list is the same at each iteration of the for loop.

     

    To accomplish the results you want, you could change your for loop to do the following:

    for i in resurse:

        b['num'] = i

        b['sqrt'] = i * i

        a.append(b.copy())

     

    This code appends a *copy* of the 'b' dictionary (with its *current* values) to the 'a' list.  This happens because running b.copy() constructs a new object that contains the value of 'b'.