【问题标题】:Check differences between dict inside lists检查列表中 dict 之间的差异
【发布时间】:2019-07-23 11:47:18
【问题描述】:

我正在尝试从两个 json 文件(olddata 和 actual_products)中获取差异。脚本的问题是输出,它应该是“没有变化”而不是我得到 y[“link”]。

我的jsonfile示例(olddata,另一个也是一样的):

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

我的代码示例:

#!/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()

“我预计输出没有变化,而是我得到了可用的项目”

【问题讨论】:

    标签: python json list dictionary


    【解决方案1】:

    如果您想使用您的代码,请将您的函数 checkdiff 更改为:

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

    输出:

    no change
    no change
    no change
    

    【讨论】:

      【解决方案2】:

      checkdiff 逻辑不正确:

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

      将遍历 9 个 (x,y) 对,其中 x 在 old_data 中,y 在 actual_products 中。因此,当您比较(例如)第一个列表的第一项与第二个列表的第二项时,它将失败。

      你可能想要的是

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

      这将在 JSON 列表中保留相同索引的 3 个 (x,y) 对上循环。

      【讨论】:

        【解决方案3】:

        在类似功能上使用pandasjoining 可以更有效地完成此任务。

        pip install pandas如果你还没有的话。

        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
        

        【讨论】:

          猜你喜欢
          • 2022-03-06
          • 1970-01-01
          • 1970-01-01
          • 2015-06-27
          • 2012-12-24
          • 1970-01-01
          • 2013-02-08
          • 2011-01-24
          • 1970-01-01
          相关资源
          最近更新 更多