Phil
Phil

Reputation: 44

Check differences between dict inside lists

I'm trying to get the differences from two json files (olddata and actual_products). The problem of the script is the output, it should be "no change" instead i'm getting y["link"].

Example of my jsonfile(olddata, the other one is the same):

[{
    "status": "sold_out",
    "link": "https://www.off---white.com/en/IT/men/products/omaa076t19e740660110#",
    "ids": "product_26781",
    "title": "\nOFF-WHITE\u2122 X NIKE T-SHIRT\n"
},
{
    "status": "sold_out",
    "link": "https://www.off---white.com/en/IT/men/products/omaa076t19e740661001#",
    "ids": "product_26782",
    "title": "\nOFF-WHITE\u2122 X NIKE T-SHIRT\n"
},
{
    "status": "in_stock",
    "link": "https://www.off---white.com/en/IT/men/products/omaa076t19e740661910#",
    "ids": "product_26783",
    "title": "\nOFF-WHITE\u2122 X NIKE T-SHIRT\n"
}]

Example of my code:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json

def load_data(file):
    with open(file) as f:
        return(json.load(f))

def save_new_data(data, file):
    with open(file, 'w') as f:
        json.dump(data, f, indent=4)

class ABC():
    def __init__(self):
        self.old_data = load_data('olddata.json')
        self.actual_products = load_data('newdata.json')

    def checkdiff(self):
        for x in self.old_data:
            for y in self.actual_products:
                if(x['status'] == "sold_out" and y['status'] == "in_stock"):
                    print("The item is available:", y["link"])
                else:
                    print("no change")

def main():
    s = ABC()
    s.checkdiff()

if __name__ == "__main__":
    main()

"i expected as output no change instead i got the item is available"

Upvotes: 1

Views: 68

Answers (3)

ncica
ncica

Reputation: 7206

if you want to use your code ,change your function checkdiff to:

def checkdiff(self):
    for i in range(len(self.old_data)):
        if(self.old_data[i]['status'] == "sold_out" and self.actual_products[i]['status'] == "in_stock"):
            print("The item is available:", self.actual_products[i]["link"])
        else:
            print("no change")

output:

no change
no change
no change

Upvotes: 1

gold_cy
gold_cy

Reputation: 14216

You can accomplish this much more efficiently using pandas and joining on similar features.

pip install pandas if you don't have it yet.

import pandas as pd

df = pd.DataFrame(new_data)
df1 = pd.DataFrame(old_data)

df.head()

             ids                                               link    status                          title
0  product_26781  https://www.off---white.com/en/IT/men/products...  sold_out  \nOFF-WHITE™ X NIKE T-SHIRT\n
1  product_26782  https://www.off---white.com/en/IT/men/products...  sold_out  \nOFF-WHITE™ X NIKE T-SHIRT\n
2  product_26783  https://www.off---white.com/en/IT/men/products...  in_stock  \nOFF-WHITE™ X NIKE T-SHIRT\n

joined = pd.merge(df, df1, how='left', on='ids', suffixes=('_new', '_old'))

joined.where(joined.status_new != joined.status_old).link_new.dropna()
Series([], Name: link_new, dtype: object)

joined.where(joined.status_new == joined.status_old).link_new.dropna() 
0    https://www.off---white.com/en/IT/men/products...
1    https://www.off---white.com/en/IT/men/products...
2    https://www.off---white.com/en/IT/men/products...
Name: link_new, dtype: object

Upvotes: 0

Leporello
Leporello

Reputation: 658

checkdiff has incorrect logic:

for x in self.old_data:
    for y in self.actual_products:

will loop over the 9 (x,y) pairs where x is in old_data and y in actual_products. It will therefore fail when you compare (e.g.) the first item of the first list with the second item of the second list.

What you probably want is

for x, y in zip(self.old_data, self.actual_products):

which will loop on the 3 (x,y) pairs where the same index in the JSON list is kept.

Upvotes: 1

Related Questions