Reputation: 807
I'm creating a dictionary in python. I'm getting same objects stored in dictionary while I loop through object. Where am I doing wrong?
I tried dict()
, however, I'm avoiding dict()
.
Code I've tried is here:
image_dict = {}
#query for getting objects
images = Image_history.objects.all()
for image in images:
image_history = dict({
"type": image.image_type,
"timestamp": image.last_updated_timestamp,
})
image_dict.append(image_history)
My problem is when I use this following method to create dictionary in python:
image_dict = {}
image_list = {}
# list of image_details
image_list["image_details"] = []
#query for getting objects
images = Image_history.objects.all()
#looping through object and storing in dictionary
for image in images:
image_dict['type']= image.image_type
image_dict['timestamp']= image.last_updated_timestamp
#appending all those objects in loop to image_list
image_list["image_details"].append(image_dict)
I expect the output to be a list of different objects. But, I'm getting list of same duplicate objects. Expected output:
{
"image_detail":[
{
"type": "png",
"timestamp": "1-12-18"
},
{
"type": "jpeg",
"timestamp": "1-1-19"
}
]
}
Actual output I'm getting:
{
"image_detail":[
{
"type": "jpeg",
"timestamp": "1-1-19"
},{
"type": "jpeg",
"timestamp": "1-1-19"
}
]
}
Upvotes: 2
Views: 10617
Reputation: 7353
You need to use a copy of image_history
dict as otherwise, you are just adding multiple references of the same dict. In case of not using image_history.copy()
you will find each element in the image_dict
to have the same value as the last image object in the for
loop.
Try the following. I have used dict.update()
. I am also using the index derived from enumeration of the images
. An additional benefit of this approach is that you could easily load it up as a dataframe to view the data.
image_dict = dict()
#query for getting objects
images = Image_history.objects.all()
for i, image in enumerate(images):
image_history = {
"type": image.image_type,
"timestamp": image.last_updated_timestamp,
}
image_dict.update({i: image_history.copy()})
# Optionally visualize the data in a dataframe
import pandas as pd
df = pd.DataFrame(image_dict).T
df.head()
Concise version of your code using dict comprehension.
# dict of image_history dicts
image_dict = dict((i, {"type": image.image_type,
"timestamp": image.last_updated_timestamp,
}) for i, image in enumerate(images))
Concise version of your code using list comprehension.
# list of image_history dicts
image_list = [{"type": image.image_type,
"timestamp": image.last_updated_timestamp,
}) for image in images)
Upvotes: 0
Reputation: 3624
Edit your code to:
image_list = {}
# list of image_details
image_list["image_details"] = []
#query for getting objects
images = Image_history.objects.all()
#looping through object and storing in dictionary
for image in images:
image_dict = {}
image_dict['type']= image.image_type
image_dict['timestamp']= image.last_updated_timestamp
#appending all those objects in loop to image_list
image_list["image_details"].append(image_dict)
Your are editing the same dictionary object, you just have to create new one at each iteration. Dictionary (created using dict
or {}
) is mutable objects in python, I suggest you read more about mutability in python. And I suggest more compact way to build your list, using list comprehensions:
image_list["image_details"] = [
{
'type': image.image_type,
'timestamp': image.last_updated_timestamp
} for image in images
]
Note: you can create immutable dictionary in python, but this off-topic.
Upvotes: 2
Reputation: 59184
You are mutating the same image_dict
object, which in turn modifies existing references to that object (i.e. previous dictionary values).
Why do you avoid constructing a new dict
? It is the only way to create separate dictionaries.
Alternatively you can move image_dict = {}
into the for
loop:
...
for image in images:
image_dict = {}
image_dict['type']= image.image_type
...
Upvotes: 1