0
def gibsSample(pB,pC,pA_B,pD_BC,pE_D,pF_C,label_A,label_B,label_C,label_D,label_E,label_F,T):
    #initial state
    sample=['A=F','B=n','C=F','D=h','E=F','F=F']
    sampleState=[]
    for i in range(T):
        #draw sample A from p(A | B,C,D,E,F)
        sample_A=sampleA(sample,pA_B)
        sample[0]=sample_A
        #draw sample B from p(B | A,C,D,E,F)
        sample_B=sampleB(sample,pB,pA_B,pD_BC)
        sample[1]=sample_B
        #draw sample C from p(C | A,B,D,E,F)
        sample_C=sampleC(sample,pC,pD_BC,pF_C)
        sample[2]=sample_C
        #draw sample D from p(D | A,B,C,E,F)
        sample_D=sampleD(sample,pD_BC,pE_D)
        sample[3]=sample_D
        #draw sample E from p(E | A,B,C,D,F)
        sample_E=sampleE(sample,pE_D)
        sample[4]=sample_E
        #draw sample F from p(F | A,B,C,D,E)
        sample_F=sampleF(sample,pF_C)
        sample[5]=sample_F
        sampleState.append(sample)
    return sampleState

I wrote a sample algorithm. Every time after I sampled from one distribution, the element in variable 'sample' will be modified and after a circle, I want to append it in the list 'sampleState'. But why it seems the 'sampleState' only appended the initial 'sample' but not the sample I modified? I iterated the loop for 2000 times and all the elements in 'sampleState' are just the same with the initial state, but I checked the 'sample' in every iteration there was no problem.

hidemyname
  • 3,791
  • 7
  • 27
  • 41

2 Answers2

1

Everytime you append sample to the list, you are appending a reference to the exact same object.

After each loop you are changing the values inside this object (the value at each index of the sample list), so if all objects in your list point to the same object, they will all see the same value.

To fix this, create a new list at the end of each loop:

    def gibsSample(pB,pC,pA_B,pD_BC,pE_D,pF_C,label_A,label_B,label_C,label_D,label_E,label_F,T):
        #initial state
        sample=['A=F','B=n','C=F','D=h','E=F','F=F']
        sampleState=[]
        for i in range(T):
            #draw sample A from p(A | B,C,D,E,F)
            sample_A=sampleA(sample,pA_B)
            sample[0]=sample_A
            #draw sample B from p(B | A,C,D,E,F)
            sample_B=sampleB(sample,pB,pA_B,pD_BC)
            sample[1]=sample_B
            #draw sample C from p(C | A,B,D,E,F)
            sample_C=sampleC(sample,pC,pD_BC,pF_C)
            sample[2]=sample_C
            #draw sample D from p(D | A,B,C,E,F)
            sample_D=sampleD(sample,pD_BC,pE_D)
            sample[3]=sample_D
            #draw sample E from p(E | A,B,C,D,F)
            sample_E=sampleE(sample,pE_D)
            sample[4]=sample_E
            #draw sample F from p(F | A,B,C,D,E)
            sample_F=sampleF(sample,pF_C)
            sample[5]=sample_F
            sampleState.append(list(sample)) # here you create a copy of your "sample"
        return sampleState

Alternate solution

Because you are using a list of a fixed size, you may also want to use a 6-tuple:

def gibsSample(pB,pC,pA_B,pD_BC,pE_D,pF_C,label_A,label_B,label_C,label_D,label_E,label_F,T):
    #initial state
    sample=('A=F','B=n','C=F','D=h','E=F','F=F')
    sampleState=[]
    for i in range(T):
        #draw sample A from p(A | B,C,D,E,F)
        sample_A=sampleA(sample,pA_B)

        #draw sample B from p(B | A,C,D,E,F)
        sample_B=sampleB(sample,pB,pA_B,pD_BC)

        #draw sample C from p(C | A,B,D,E,F)
        sample_C=sampleC(sample,pC,pD_BC,pF_C)

        #draw sample D from p(D | A,B,C,E,F)
        sample_D=sampleD(sample,pD_BC,pE_D)

        #draw sample E from p(E | A,B,C,D,F)
        sample_E=sampleE(sample,pE_D)

        #draw sample F from p(F | A,B,C,D,E)
        sample_F=sampleF(sample,pF_C)

        t = (sample_A, sample_B, sample_C, sample_D, sample_E, sample_F)
        sampleState.append(t)
    return sampleState
Martin Konecny
  • 57,827
  • 19
  • 139
  • 159
0

What you are looking for is static variables in functions. As it described in this question, you need to replace sample with gibsSample.sample everywhere in your code:

def gibsSample(pB,pC,pA_B,pD_BC,pE_D,pF_C,label_A,label_B,label_C,label_D,label_E,label_F,T):
    #initial state
    gibsSample.sample=['A=F','B=n','C=F','D=h','E=F','F=F']
    sampleState=[]
    for i in range(T):
        #draw sample A from p(A | B,C,D,E,F)
        sample_A=sampleA(gibsSample.sample,pA_B)
        gibsSample.sample[0]=sample_A
        #draw sample B from p(B | A,C,D,E,F)
        sample_B=sampleB(gibsSample.sample,pB,pA_B,pD_BC)
        gibsSample.sample[1]=sample_B
        #draw sample C from p(C | A,B,D,E,F)
        sample_C=sampleC(gibsSample.sample,pC,pD_BC,pF_C)
        gibsSample.sample[2]=sample_C
        #draw sample D from p(D | A,B,C,E,F)
        sample_D=sampleD(gibsSample.sample,pD_BC,pE_D)
        gibsSample.sample[3]=sample_D
        #draw sample E from p(E | A,B,C,D,F)
        sample_E=sampleE(gibsSample.sample,pE_D)
        gibsSample.sample[4]=sample_E
        #draw sample F from p(F | A,B,C,D,E)
        sample_F=sampleF(gibsSample.sample,pF_C)
        gibsSample.sample[5]=sample_F
        sampleState.append(gibsSample.sample)
        gibsSample.sample = [None] * 6
    return sampleState
Community
  • 1
  • 1
akarilimano
  • 1,034
  • 1
  • 10
  • 17
  • This doesn't address the root of the problem. Even if assigning attributes to functions was considered idiomatic, you still have each iteration of the loop modifying the exact same list object. – Martin Konecny May 09 '15 at 05:21
  • @MartinKonecny ok, I get it, I didn`t understand the question he asked. – akarilimano May 09 '15 at 05:28