Home > Net >  Changing the parameters of elements in a list individually
Changing the parameters of elements in a list individually

Time:03-18

I want to change a parameters in a list of elements QF and QD as following: Lattice is a list includes these elements for example :

lattice = [QF, QD, QF, QD]

And the indexes of these elements in the list are given in quad_indexes.

QF and QD has two parameters (K and FamName):

QF.K = 1.7 and QD.K = -2.1
QF.FamName = 'QF'
QD.FamName = 'QD'

I want to gave the random value for the parameter K for each element individually

I tried:

    i =0
    Quad_strength_err =[]
    while(i < len(quad_indexes)):

         if(lattice[quad_indexes[i]].FamName == 'QF'):
              lattice[quad_indexes[i]].K *= (1   errorQF*random())
              i  = 1

         elif(lattice[quad_indexes[i]].FamName == 'QD'):
             lattice[quad_indexes[i]].K *= (1   errorQD * random())
             i  = 1
    
    for j in quad_indexes:
       quad_strength_err = lattice[j].K
       Quad_strength_err.append(quad_strength_err)

The problem is when i print (Quad_strength_err) i got fixed value for each of QF and QD, for example:

[1.8729820159805597, -2.27910323371567, 1.8729820159805597, -2.27910323371567]

I am looking foe a result for example:

[1.7729820159805597, -2.17910323371567, 1.8729820159805597, -2.27910323371567]

CodePudding user response:

TL;DR

You need to make copies of QF and QD - you're making aliases.

The problem

The problem is almost certainly due to aliasing.

When you initialize lattice with this line:

lattice = [QF, QD, QF, QD]

what you are doing is creating a structure with two pointers to QF and two pointers to QD.

In your loop, you then modify QF twice, once via lattice[0] and again via lattice[2], and ditto for QD.

The solution

What you need to do is create copies, maybe shallow, maybe deep.

Try this option:

from copy import copy
lattice = [copy(QF), copy(QD), copy(QF), copy(QD)]

and if that still doesn't work, you might need a deepcopy:

from copy import deepcopy
lattice = [deepcopy(QF), deepcopy(QD), deepcopy(QF), deepcopy(QD)]

Or, a more compact version of the same code, just cause I like comprehensions:

from copy import deepcopy
lattice = [deepcopy(x) for x in (QF, QD, QF, QD)]

CodePudding user response:

If your code is correct, you can't expect a different result for your first and third element of lattice (resp second and last), since it's (to simplify) the same element.

Using id, you can easily show that, lattice[0] and lattice[2] share the same id, therefore modifying lattice[0] will modify lattice[2].

You can duplicate each object QF and QD to git rid of this behavior

CodePudding user response:

I tryed to build a working sample of your problem starting by building simple QF and QD classes :

from random import random

class QF():
    def __init__(self):
        self.K =  1.7
        self.FamName = "QF"
        
class QD():
    def __init__(self):
        self.K =  -2.1
        self.FamName = "QD"    

then I create the lattice with different instance of the classis by calling them with ()

lattice = [QF(), QD(), QF(), QD()]

I think your mistake comes from this step as QF refers to the class it self and QF creats a brand new instance that you can modify separatly from the other one. For example if you do QF.K = 3 and then a = QF(), a.K should return you 3.

finally I apply some randomness using the random imported previously :

for i in lattice:
    if i.FamName == "QF":
        i.K = (1   errorQF*random())
    elif i.FamName == "QD":
        i.K = (1   errorQD*random())


form which I get :

print(*[i.K for i in lattice])

>>>> 1.148989048860669 0.9324164812782919 1.0652187255939742 0.6860911849022292

  • Related