2

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"
        }
     ]
}
0

3 Answers 3

2

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.

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

Comments

1

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
    ...

Comments

0

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()

Dict Comprehension

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))

List Comprehension

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.