4 回答

TA貢獻(xiàn)1906條經(jīng)驗(yàn) 獲得超3個(gè)贊
您可以使用 adict來(lái)累積項(xiàng)目。
字典可以存儲(chǔ)idas 鍵和列表項(xiàng)作為值。如果不存在具有相同鍵的項(xiàng),則僅在字典中插入一項(xiàng);如果它確實(shí)比較updated_at值并在需要時(shí)更新字典。
def generate_new_list(my_list):
counts = {}
for d in my_list:
item_id = d['id']
if item_id in counts:
if d['updated_at'] > counts[item_id]['updated_at']:
counts[item_id] = d
else:
counts[item_id] = d
return list(counts.values())
還有一些注意事項(xiàng):
如果您想保留原始順序,請(qǐng)確保您使用的是 Python 3.7(它保證 dicts 按插入順序排序)或使用 OrderedDict。使用標(biāo)準(zhǔn)字典,您必須首先彈出條目,因?yàn)樘鎿Q不會(huì)更改字典順序(因此每個(gè)項(xiàng)目都將按照其 id 第一次出現(xiàn)的順序輸出),而ordereddict 對(duì)該用例有特殊支持(move_to_end) .
您還可以通過(guò)使用dict.get和“空對(duì)象模式”刪除特殊情況:
MISSING = {'updated_at': '0'} # pseudo-entry smaller than all possible
def generate_new_list(my_list):
counts = {}
for d in my_list:
if d['updated_at'] > counts.get(d['id'], MISSING):
counts[d['id']] = d
return list(counts.values())
一種非字典替代方案(盡管非常不保存順序)是按(id,updated_by)排序,按id分組,然后只保留最后一個(gè)條目。我不認(rèn)為 stdlib 提供了開(kāi)箱即用的最后一個(gè)操作(islice 不接受負(fù)索引),因此您要么必須手動(dòng)執(zhí)行此操作,要么首先將子條目具體化為列表。

TA貢獻(xiàn)1877條經(jīng)驗(yàn) 獲得超6個(gè)贊
兩種解決方案,一種使用字典,另一種通過(guò)排序和分組:
from itertools import groupby
my_list = [
{"id": "UU7t", "updated_at": "2020-01-06_16-40-00", "summary": "Renewed"},
{"id": "yT8h", "updated_at": "2020-01-07_18-24-22", "summary": "Renewed"},
{"id": "i8Po", "updated_at": "2020-01-08_13-16-36", "summary": "Renewed"},
{"id": "yT8h", "updated_at": "2020-01-13_18-24-05", "summary": "Deleted"},
{"id": "7uYg", "updated_at": "2020-01-18_23-37-19", "summary": "Transferred"},
]
def newest_id(seq):
"""Keep id with most recent updated_at
Return a list of kept items.
"""
td = {}
for e in seq:
key = e['id']
if key not in td or td[key]['updated_at'] < e['updated_at']:
td[key] = e
return list(td.values())
def newest_id2(seq):
"""Keep id with most recent updated_at
Return a sorted list of kept items.
"""
tl = sorted(seq, key=lambda e: (e['id'], e['updated_at']), reverse=True)
return [next(g) for _, g in groupby(tl, key=lambda e: e['id'])]
res1 = newest_id(my_list)
res2 = newest_id2(my_list)
# Check result
res1.sort(key=lambda e: e['id'], reverse=True)
print(res1 == res2)

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超13個(gè)贊
一種方法是改變 dict 的結(jié)構(gòu)。
my_list = [
{"id": "UU7t", "updated_at": "2020-01-06_16-40-00", "summary": "Renewed"},
{"id": "yT8h", "updated_at": "2020-01-07_18-24-22", "summary": "Renewed"},
{"id": "i8Po", "updated_at": "2020-01-08_13-16-36", "summary": "Renewed"},
{"id": "yT8h", "updated_at": "2020-01-13_18-24-05", "summary": "Deleted"},
{"id": "7uYg", "updated_at": "2020-01-18_23-37-19", "summary": "Transferred"},
]
def getNewUpdated(myList):
newList = {}
for element in myList:
if (element["id"] not in newList):
newList[element["id"]] = element
elif (element["updated_at"] >= newList[element["id"]]["updated_at"]):
newList[element["id"]] = element
return newList
print(getNewUpdated(my_list))
在這里,我們正在重構(gòu)dict,使“id”是key,所有元素都是“values”,然后迭代您提供的列表以檢查“id”是否已經(jīng)存在于newList中,如果存在,則只需更新相同的記錄(前提是更新時(shí)間是新的),否則添加新記錄。
輸出是這樣的:
{
'i8Po': {'summary': 'Renewed', 'id': 'i8Po', 'updated_at': '2020-01-08_13-16-36'},
'yT8h': {'summary': 'Deleted', 'id': 'yT8h', 'updated_at': '2020-01-13_18-24-05'},
'7uYg': {'summary': 'Transferred', 'id': '7uYg', 'updated_at': '2020-01-18_23-37-19'},
'UU7t': {'summary': 'Renewed', 'id': 'UU7t', 'updated_at': '2020-01-06_16-40-00'}
}

TA貢獻(xiàn)1873條經(jīng)驗(yàn) 獲得超9個(gè)贊
使用pandas
import pandas as pd
df = pd.DataFrame(my_list)
df = df.sort_values(by="updated_at").drop_duplicates(subset=["id"], keep="last")
my_list = df.to_dict(orient="records")
輸出:
[{'id': 'UU7t', 'summary': 'Renewed', 'updated_at': '2020-01-06_16-40-00'},
{'id': 'i8Po', 'summary': 'Renewed', 'updated_at': '2020-01-08_13-16-36'},
{'id': 'yT8h', 'summary': 'Deleted', 'updated_at': '2020-01-13_18-24-05'},
{'id': '7uYg', 'summary': 'Transferred', 'updated_at': '2020-01-18_23-37-19'}]
添加回答
舉報(bào)