Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Appending instanse attribute as list in for loop

I’ve written a simplified example of the logic of the class, which I find confusing.

class Result:

    def __init__(self):
        self.limit = 10
        self.params_with_error = []

    def get_result(self, offset_range):
        qs = {'limit': self.limit}
        for chunk in range(offset_range):
            print(f'chunk: {chunk}')
            print(f'__Params_with_error__: {self.params_with_error}')

            qs.update({'offset': chunk * self.limit})

            if chunk in (5, 7):
                print('IF condition')
                self.params_with_error.append(qs)
        print(f'Result param: {self.params_with_error}')

result = Result()
result.get_result(10)

And this code return

chunk: 0
__Params_with_error__: []
chunk: 1
__Params_with_error__: []
chunk: 2
__Params_with_error__: []
chunk: 3
__Params_with_error__: []
chunk: 4
__Params_with_error__: []
chunk: 5
__Params_with_error__: []
IF condition
chunk: 6
__Params_with_error__: [{'limit': 10, 'offset': 50}]
chunk: 7
__Params_with_error__: [{'limit': 10, 'offset': 60}]
IF condition
chunk: 8
__Params_with_error__: [{'limit': 10, 'offset': 70}, {'limit': 10, 'offset': 70}]
chunk: 9
__Params_with_error__: [{'limit': 10, 'offset': 80}, {'limit': 10, 'offset': 80}]
Result param: [{'limit': 10, 'offset': 90}, {'limit': 10, 'offset': 90}]

And I don’t understand at all how such a result can come about.
I expect that if the if condition occurs twice, the final result is equivalent to

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

[{'limit': 10, 'offset': 50}, {'limit': 10, 'offset': 70}]

Why does self.params_with_error continue to change further in the loop? I also don’t understand why the final value of Result param: [{'limit': 10, 'offset': 90}, {'limit': 10, 'offset': 90}]
How do I get the results I want?

>Solution :

dictionaries are mutable, you only created 1 dictionary in your entire code snippet.

qs = {'limit': self.limit}

everything else in the code just references or updates this dictionary, so your final result just has 2 references to the same dictionary, it was never copied.

self.params_with_error = [qs, qs]

to get the result you want, just append a copy of your dictionary not a reference to it.

import copy

self.params_with_error.append(copy.copy(qs))
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading