比较两个 JSON 结果并生成新条目的新 JSON (Python)
Posted
技术标签:
【中文标题】比较两个 JSON 结果并生成新条目的新 JSON (Python)【英文标题】:Compare two JSON results and make new JSON of new entries (Python) 【发布时间】:2021-11-29 00:49:42 【问题描述】:我正在查询一个 API 以尝试在 JSON 中查找新条目,我被困在如何“减去”这两个列表上,以便获得一个新的 JSON 对象,其中只有两个列表之间的新项目。
我现在做的是:
-
我正在查询 API。
将 JSON 结果存储到变量中。
等待 30 秒。
再次查询 API。
比较 PreviousJSON == NewJSON
如果有区别,那么:
^^ 这是我卡住的地方,我可以比较值,但我不知道如何只找到新值并迭代它们。
我基本上是在监控这个 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.
所以这两个问题是:
-
有没有更好的方法来比较两个 JSON 对象中的两个相同条目(未排序)
有没有办法获得仅包含 PrevListings 中不存在的新条目的第三个 JSON。
这是 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
谢谢!
【问题讨论】:
您应该比较究竟什么。请添加详细说明。 您要比较键(0000)还是值(数据)? 我想比较 Last Sale Price,如果数据不同,则将整个节点(连同所有子节点)添加到仅包含更新数据的新字典中。那,并且还获取新条目(在 JSON B 中但不在 JSON A 中的 ID,并将它们存储在 JSON C 中(新) 【参考方案1】:试试下面的(data_1
和data_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
【讨论】:
这很有帮助,但是如果发现差异时,我想返回整个节点子节点,而不仅仅是 ID,因为我想返回新列表的元数据 只需遍历“新”ID 并执行 data_2.get('the_new_id') - 它会返回整个节点。 (代码已更新)【参考方案2】:您采用的方法取决于***键(例如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
。
【讨论】:
以上是关于比较两个 JSON 结果并生成新条目的新 JSON (Python)的主要内容,如果未能解决你的问题,请参考以下文章
Normalizr 更改原始文件 .json 或生成具有所需架构的新文件 .json?