比较两个JSON结果并创建新条目的新JSON(Python)

2024-06-25 05:18:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在查询一个API以尝试在JSON中查找新条目,我一直在研究如何“减去”这两个列表,以便得到一个新的JSON对象,该对象在这两个列表之间只有新条目

我现在做的是:

  1. 我正在查询API
  2. 将JSON结果存储到变量中
  3. 等30秒
  4. 再次查询API
  5. 如果PreviousJSON==NewJSON,则进行比较
  6. 如果有区别,那么:

^^这就是我的困境,我可以比较值,但我不知道如何只找到新值并迭代它们

我基本上在监视这个API: https://qzlsklfacc.medianetwork.cloud/nft_for_sale?collection=galacticgeckospacegarage

并试图找到新的物品和新售出的物品

现在,为了比较现有项目之间的差异,我正在执行以下操作:

# check if new listings are the same as the old listings
    if prevListings != newListings:
        await bot.get_channel(893292122298540083).send("New listings found!")
        for listingOld in prevListings:
           for listingNew in newListings:
               if listingNew['id'] == listingOld['id']:
                   if listingNew['lastSoldPrice'] is not None:
                       if listingNew['lastSoldPrice'] != listingOld['lastSoldPrice']:
                           Do something.

因此,这两个问题是:

  1. 有没有更好的方法来比较两个JSON对象(未排序)中的两个相同条目
  2. 有没有办法获得第三个JSON,其中只包含PrevListings中不存在的新条目

这是JSON响应中每个项的JSON结构

0000:
    'id':1155682
    'token_add':'HV4duJjY67DD4doX9ffvzfoaENAAkFuwz9qtbwAweDAG'
    'number':1
    'currency':'SOL'
    'price':29
    'link_img':'https://www.arweave.net/iZs-LiMAg5mIqaqxrd--EtcKhHTNtPZFPrZyIK95nUc?ext=jpeg'
    'for_sale':1
    'programId':'CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz'
    'name':'Galactic Gecko #6376'
    'description':'undefined'
    'escrowAdd':'4TULtxsixV4NLdZWqY45d4Mz5XrE4q4CfTECNcvaZDY1'
    'seller_address':'Er6QJPusC1JsUqevTjFKXtYHbgCtJkyo1DNjEBWevWut'
    'attributes':'Faction: Barada,Body: Light Pink,Armor: Planetary Kirtle,Mouth: Pensive,Helmet: Signal Deflector,Ears: Planetary Muffler,Eyes: Augmented Surveyor'
    'skin':None
    'type':'galacticgeckospacegarage'
    'ranking':None
    'buyerAdd':None
    'blockhash':None
    'lastSoldPrice':13.99

我正在使用Python 3.8

谢谢大家!


Tags: 对象httpsnoneapiidjson列表for
2条回答

尝试下面的(data_1data_2表示2个API调用的结果)

data_1 = [{'lastSoldPrice':12,'id':14},{'lastSoldPrice':18,'id':15},{'lastSoldPrice':149,'id':146}]
data_2 = [{'lastSoldPrice':12,'id':17},{'lastSoldPrice':18,'id':15},{'lastSoldPrice':142,'id':146},{'lastSoldPrice':1422,'id':166}]
# convert list to dict
data_1 = {entry.get('id'): entry for entry in data_1}
data_2 = {entry.get('id'): entry for entry in data_2}
# set operation to find new and common
new_entries = data_2.keys() - data_1.keys()
print(f'New entry ids: {new_entries}')
for _id in new_entries:
  print(f'\t {data_2.get(_id)}')
common_entries = data_2.keys() & (data_1.keys())
print(f'Common entry ids: {common_entries}')

# loop over common entries and see if there is a price change
for _id in common_entries:
  p1 = data_1.get(_id)['lastSoldPrice']
  p2= data_2.get(_id)['lastSoldPrice']
  if p1 != p2:
    print(f'Price change for id {_id}. Old price: {p1}, new price: {p2}')

输出

New entry ids: {17, 166}
     {'lastSoldPrice': 12, 'id': 17}
     {'lastSoldPrice': 1422, 'id': 166}
Common entry ids: {146, 15}
Price change for id 146. Old price: 149, new price: 142

您采取的方法取决于顶级键(例如0000)是否对单个对象唯一。如果是,您可以使用这些键来过滤返回的对象,如果不是,您需要做更多的工作

顶级密钥是ID

如果顶级键对于对象是唯一的,您可以简单地迭代新字典,看看它的键是否在现有字典中。在下面的代码中first是初始字典,second是我们的第二个响应。输出存储在字典third


third = {}  # empty dictionary for our output.
for key, data in second.items():
    if key not in first:  # is new
        third[key] = data

因此,我们迭代second字典,检查每个键是否在first字典中。如果它不是,我们将它添加到third

您也可以使用字典理解来完成此操作(相同的结果)

third = {key:value for key, value in second.items() if key not in first}

id在数据中

如果键不是ID,那么您就有一个问题:您需要通过嵌套在第一个字典数据中的内容来过滤第二个字典。我们可以为second中的每个条目迭代first字典,但这很慢

因为我们只想知道它是否在那里,所以我们可以将需要检查的值(例如id)提取到一个新变量中。因为查找速度很快,所以设置一个集合是很好的

# build a set of values from the first dictionary.
first_ids = set(o['id'] for o in first.values())

third = {}
for key, data in second.items():
    if data['id'] not in first_ids:
        third[key] = data

或者,再一次用听写理解

first_ids = set(o['id'] for o in first.values())
third = {key:value for key, value in second.items() if value['id'] not in first_ids}

如您所见,我们在first字典上迭代一次以构建我们的ID集。然后可以使用它快速测试second字典中接收的新数据是否为新数据。如果是,我们将其添加到字典third

相关问题 更多 >