简体   繁体   中英

How to create array of objects in python

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

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.

You are mutating the same image_dict object, which in turn modifies existing references to that object (ie 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
    ...

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM