1
class MyOwnClass: # list who contains the queries queries = [] # a template dict template_query = {} template_query['name'] = 'mat' template_query['age'] = '12' obj = MyOwnClass() query = obj.template_query query['name'] = 'sam' query['age'] = '23' obj.queries.append(query) query2 = obj.template_query query2['name'] = 'dj' query2['age'] = '19' obj.queries.append(query2) print obj.queries 

It gives me

[{'age': '19', 'name': 'dj'}, {'age': '19', 'name': 'dj'}] 

while I expect to have

[{'age': '23' , 'name': 'sam'}, {'age': '19', 'name': 'dj'}] 

I thought to use a template for this list because I'm gonna to use it very often and there are some default variable who does not need to be changed.

Why does doing it the template_query itself changes? I'm new to python and I'm getting pretty confused.

3 Answers 3

5

this is because you are pointing to the same dictionary each time ... and overwriting the keys ...

# query = obj.template_query - dont need this query = {} query['name'] = 'sam' query['age'] = '23' obj.queries.append(query) query2 = {} #obj.template_query-dont need this query2['name'] = 'dj' query2['age'] = '19' obj.queries.append(query2) 

this should demonstrate your problem

>>> q = {'a':1} >>> lst = [] >>> lst.append(q) >>> q['a']=2 >>> lst [{'a': 2}] >>> lst.append(q) >>> lst [{'a': 2}, {'a': 2}] 

you could implement your class differently

class MyOwnClass: # a template dict @property def template_query(): return {'name':'default','age':-1} 

this will make obj.template_query return a new dict each time

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for you're answer. The easiest way to fix it I think is to return the dict with a function as you suggested.
3

This is because query and query2 are both referring to the same object. obj.template_query, in this case.

Better to make a template factory:

def template_query(**kwargs): template = {'name': 'some default value', 'age': 'another default value', 'car': 'generic car name'} template.update(**kwargs) return template 

That creates a new dictionary every time it's called. So you can do:

>>> my_query = template_query(name="sam") >>> my_query {'name': 'sam', 'age': 'another default value', 'car': 'generic car name'} 

1 Comment

great answer :) and way to encourage better coding practice in general
1

You're copying the same dict into query2. Instead, you might want to create the needed dict by creating a function template_query() and constructing a new dict each time:

class MyOwnClass: # a template dict def template_query(): d = {} d['name'] = 'mat' d['age'] = '12' d['car'] = 'ferrari' return d 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.