1

I have some problem here. Please look at my code and I don't know what's wrong in the code. It is simple but the results are confusing me. I attached the code below.

import numpy as np
import matplotlib.pyplot as plt

def S(xc):
    N=len(xc)
    r=0.0
    s=0.0

    # calculation quartile
    for m in range(0,N-1):
        for n in range(m+1,N):
            if (xc[m] > xc[n]):
                q=xc[m]
                xc[m]=xc[n]
                xc[n]=q

    if (N % 4 < 2):
        q=(xc[N-N/4-1] + xc[N-N/4])*0.5-(xc[N/4-1]+xc[N/4])*0.5
    else:
        q=xc[N-N/4-1]-xc[N/4]

    #calculation standard deviation

    for m in range(0,N):
        r+=xc[m]
        s+=xc[m]*xc[m]
    r=np.sqrt(s/N-(r/N)*(r/N))

    #calculation
    if (q<r):
        s=q
    else:
        s=r
    hasil=0.9*(s/1.34)*pow(N,-0.2)
    return hasil

fc=0.3
fm=0.02
mu=1
Nsim=10


bb=[]
for nn in range(0,Nsim):
    bb.append((1+(mu*np.cos(2*np.pi*fm*nn)))*np.cos(2*np.pi*fc*nn))

print bb
print S(bb)
print bb

The code works while I just delete the function of "S" in the main function, however, after the "S" function, the data on variable "bb" was different even though I just print the same variable. I don't understand what happened.

I appreciate your help. Thanks a lot

Alvin

Alvin
  • 11
  • 1
  • Not sure why are you so surprised, after all you're assigning values into the array in this function, such as `xc[n]=q`... – Nir Alfasi Aug 22 '17 at 00:36

3 Answers3

1

Calling S(bb) changes the contents of bb through statements like xc[m]=xc[n].

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
0

This is the (un)expected behaviour when working with mutable types in Python. In your case, passing in a mutable type bb, which is a list, to the function S.

You pass bb into S() with the variable name xc and within S, you've got the lines xc[m]=xc[n] and xc[n]=q. This changes the list xc, which is the same list bb points to.

Simpler example of what is happening:

>>> def funny(some_list):
...     for i in range(len(some_list)):  # terrible way to iterate over a list
...         some_list[i] = some_list[i] * 2  # assigning back to the list
...
>>>
>>> alist = [1, 2, 3]
>>>
>>> funny(alist)
>>> alist
[2, 4, 6]
>>>

alist got changed after calling funny() because of the assignment to the list which I passed in.

If you don't want that behaviour, either pass in a copy of the list as S(bb[:]) or create a new list inside S by creating a copy of xc.

aneroid
  • 12,983
  • 3
  • 36
  • 66
0

bb is a list, and lists are mutable.

Even though S() refers to its argument by a different name, xc, ultimately it refers to the same object. When S() executes statements such as xc[n]=q, the underlying list object is altered.

John Gordon
  • 29,573
  • 7
  • 33
  • 58