Home > Back-end >  Problems appending objects to a list. Data is added correctly, but when verified it is not what I ad
Problems appending objects to a list. Data is added correctly, but when verified it is not what I ad

Time:06-26

I need to fill a db with fake data. To do so I'm creating a list of objects. I generate 10 timestamps, and for each timestamp I create an object, add the timestamp and some randomly assigned data, then it is appended to the list 5 times; each time given a unique id ('tag'). This format is quite specific as I am trying to simulate what the real data will be like.

Everytime I append a value, I run a print to show that the data is correct. Then when I am finished the entire operation, I print the entire list to double check. The first print value returns perfect. Yet the second tells me that I have 10 instances of identical data - my tag value is the same for 5 instances, then jumps up by 5, and repeat.

What am I missing?

cultures = [
    {
        'name': 'Pink Oyster',
        'scientific_name': 'Pleurotus djamor'
    },
    {
        'name': 'Brown Oyster',
        'scientific_name': 'Pleurotus ostreatus'
    },
    {
        'name': 'Blue Oyster',
        'scientific_name': 'Pleurotus Columbinus'
    },
    {
        'name': 'Chestnut',
        'scientific_name': 'Pholiota Adiposa'
    },
    {
        'name': 'Shiitake',
        'scientific_name': 'Lentinula edodes'
    },
    {
        'name': "Lion's Mane",
        'scientific_name': 'Hericium erinaceus'
    },
]

times = pd.date_range(start="2022-01-01",end="2022-07-20", periods=10).to_pydatetime().tolist()

data = []
count = 0
for time in times:
    raw = {}

    for key, value in cultures[randrange(0,5)].items():
        raw[key] = value
    raw['generation'] = randrange(0, 10)
    raw['stage'] = randrange(0, 3)
    raw['user_id'] = 1
    raw['created_at'] = time
    raw['updated_at'] = time

    for i in range(5):
        raw['tag'] = count
        count  = 1
        
        data.append(raw) 
        #shows my data has been appended correctly
        print(data[-1])

#???????
print(data)

example first print - tag value increases by 1

{'name': 'Blue Oyster', 'scientific_name': 'Pleurotus Columbinus', 'generation': 5, 'stage': 1, 'user_id': 1, 'created_at': datetime.datetime(2022, 1, 1, 0, 0), 'updated_at': datetime.datetime(2022, 1, 1, 0, 0), 'tag': 0}
{'name': 'Blue Oyster', 'scientific_name': 'Pleurotus Columbinus', 'generation': 5, 'stage': 1, 'user_id': 1, 'created_at': datetime.datetime(2022, 1, 1, 0, 0), 'updated_at': datetime.datetime(2022, 1, 1, 0, 0), 'tag': 1}
{'name': 'Blue Oyster', 'scientific_name': 'Pleurotus Columbinus', 'generation': 5, 'stage': 1, 'user_id': 1, 'created_at': datetime.datetime(2022, 1, 1, 0, 0), 'updated_at': datetime.datetime(2022, 1, 1, 0, 0), 'tag': 2}
{'name': 'Blue Oyster', 'scientific_name': 'Pleurotus Columbinus', 'generation': 5, 'stage': 1, 'user_id': 1, 'created_at': datetime.datetime(2022, 1, 1, 0, 0), 'updated_at': datetime.datetime(2022, 1, 1, 0, 0), 'tag': 3}
{'name': 'Blue Oyster', 'scientific_name': 'Pleurotus Columbinus', 'generation': 5, 'stage': 1, 'user_id': 1, 'created_at': datetime.datetime(2022, 1, 1, 0, 0), 'updated_at': datetime.datetime(2022, 1, 1, 0, 0), 'tag': 4}

example second print - tag is stuck at 4

[{'name': 'Blue Oyster', 'scientific_name': 'Pleurotus Columbinus', 'generation': 5, 'stage': 1, 'user_id': 1, 'created_at': datetime.datetime(2022, 1, 1, 0, 0), 'updated_at': datetime.datetime(2022, 1, 1, 0, 0), 'tag': 4}, {'name': 'Blue Oyster', 'scientific_name': 'Pleurotus Columbinus', 'generation': 5, 'stage': 1, 'user_id': 1, 'created_at': datetime.datetime(2022, 1, 1, 0, 0), 'updated_at': datetime.datetime(2022, 1, 1, 0, 0), 'tag': 4}, {'name': 'Blue Oyster', 'scientific_name': 'Pleurotus Columbinus', 'generation': 5, 'stage': 1, 'user_id': 1, 'created_at': datetime.datetime(2022, 1, 1, 0, 0), 'updated_at': datetime.datetime(2022, 1, 1, 0, 0), 'tag': 4}, {'name': 'Blue Oyster', 'scientific_name': 'Pleurotus Columbinus', 'generation': 5, 'stage': 1, 'user_id': 1, 'created_at': datetime.datetime(2022, 1, 1, 0, 0), 'updated_at': datetime.datetime(2022, 1, 1, 0, 0), 'tag': 4}, {'name': 'Blue Oyster', 'scientific_name': 'Pleurotus Columbinus', 'generation': 5, 'stage': 1, 'user_id': 1, 'created_at': datetime.datetime(2022, 1, 1, 0, 0), 'updated_at': datetime.datetime(2022, 1, 1, 0, 0), 'tag': 4},

How am i changing the values of previous appends when I change the value after I append the data

CodePudding user response:

In python, stuff is passed around by reference to value. It basically means that primitive types (int, str, float) are passed by value, and complex types (list, object, dict) are passed by reference. So if you add raw to the list, you actually add the reference to it. You then change its contents, and add it again.

Instead of doing data.append(raw) try data.append(raw.copy()).

CodePudding user response:

You need a fresh copy of raw each time round the loop:

for i in range(5):
    raw1 = raw.copy()
    raw1['tag'] = count
    count  = 1
        
    data.append(raw1)
  • Related