我有一個 JSON 檔案,它是一個字典串列。
我想洗掉基于“book_id”鍵的重復字典,并只保留其中一個具有“id”鍵的最大值)
例子:
book_list = [
{"id": 20, "user_id": 8, "device_id": 1, "book_id": 81},
{"id": 19, "user_id": 8, "device_id": 1, "book_id": 81},
{"id": 18, "user_id": 8, "device_id": 1, "book_id": 81},
{"id": 17, "user_id": 8, "device_id": 1, "book_id": 78},
{"id": 16, "user_id": 8, "device_id": 1, "book_id": 77},
{"id": 15, "user_id": 8, "device_id": 1, "book_id": 77},
{"id": 13, "user_id": 8, "device_id": 1, "book_id": 75}]
我想要的是這樣的:
new_list = [
{'id': 20, 'user_id': 8, 'device_id': 1, 'book_id': 81},
{'id': 17, 'user_id': 8, 'device_id': 1, 'book_id': 78},
{'id': 16, 'user_id': 8, 'device_id': 1, 'book_id': 77},
{'id': 13, 'user_id': 8, 'device_id': 1, 'book_id': 75}]
用這個示例串列執行下面的代碼效果很好,我得到了想要的結果。但是在我的 JSON 檔案資料上運行時遇到了一些問題,無法正確分組它們,它會洗掉一些重復的值,但不是全部:
for key, value in groupby(book_list, key=lambda v: v["book_id"]):
newlist.append(max(list(value), key=lambda v: v["id"]))
我也嘗試了這段代碼,它可以洗掉所有重復的資料,但它會獲得具有最小 id 的資料(它實際上覆寫了最后一個字典):
new_list = list({v['book_id']: v for v in book_list}.values())
我更喜歡可以在 O(1) 中完成的代碼行(如果可能的話)
uj5u.com熱心網友回復:
試試看:
book_list = [
{"id": 20, "user_id": 8, "device_id": 1, "book_id": 81},
{"id": 19, "user_id": 8, "device_id": 1, "book_id": 81},
{"id": 18, "user_id": 8, "device_id": 1, "book_id": 81},
{"id": 17, "user_id": 8, "device_id": 1, "book_id": 78},
{"id": 16, "user_id": 8, "device_id": 1, "book_id": 77},
{"id": 15, "user_id": 8, "device_id": 1, "book_id": 77},
{"id": 13, "user_id": 8, "device_id": 1, "book_id": 75}
]
new_book_list = []
_book_id_list = set() # ids added here # suggested by "MYousefi"
for book in book_list:
if book['book_id'] not in _book_id_list:
_book_id_list.add(book['book_id']) # dont accept a book Twice
new_book_list.append(book)
print(f'{new_book_list = }')
謝謝MYousefi
uj5u.com熱心網友回復:
用于dict.setdefault創建串列字典的字典。遍歷外部字典的值并找到內部字典的最大鍵:
temp = {}
for d in book_list:
temp.setdefault(d['book_id'], {}).setdefault(d['id'], []).append(d)
new_list = [v[max(v)] for v in temp.values()]
輸出:
[[{'id': 20, 'user_id': 8, 'device_id': 1, 'book_id': 81}],
[{'id': 17, 'user_id': 8, 'device_id': 1, 'book_id': 78}],
[{'id': 16, 'user_id': 8, 'device_id': 1, 'book_id': 77}],
[{'id': 13, 'user_id': 8, 'device_id': 1, 'book_id': 75}]]
再一次,看起來串列已經排序,所以我們可以反轉book_list并讀取串列,將其反轉回來:
new_list = list({d['book_id']: d for d in book_list[::-1]}.values())[::-1]
uj5u.com熱心網友回復:
如果您按 'id' 對串列進行排序,然后根據 'book_id' 形成一個臨時字典,則只有具有最大 id 的字典將保留為每個重復的 'book_id' 鍵的值:
ids = {b['book_id']:b for b in sorted(book_list,key=lambda b:b['id'])}
book_list = list(ids.values())
print(*book_list,sep='\n')
{'id': 13, 'user_id': 8, 'device_id': 1, 'book_id': 75}
{'id': 16, 'user_id': 8, 'device_id': 1, 'book_id': 77}
{'id': 17, 'user_id': 8, 'device_id': 1, 'book_id': 78}
{'id': 20, 'user_id': 8, 'device_id': 1, 'book_id': 81}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/418705.html
標籤:
上一篇:有沒有一種干凈的方法可以用Python中的字典呼叫方法來構建一行代碼?
下一篇:如何在dict中洗掉對
