对于这个令人费解的标题,我深表歉意。我需要按相当具体的标准过滤字典列表。
通常,我会做一个列表理解,但我对逻辑并不乐观。
这是一个示例列表:
list_dict = [{'item_id': '000354', 'ts_created': '11/12/2013', 'item_desc': 'a product'},
{'item_id': '000354', 'ts_created': '11/13/2013', 'item_desc': 'a product'},
{'item_id': '000355', 'ts_created': '11/12/2013', 'item_desc': 'a different product'}]
您会注意到,除了 'ts_created' 之外,前两个字典项是相同的。
我想创建一个新字典,保留具有最早时间戳的所有项目,并丢弃其余项目。
编辑:从标题中删除了“优雅”,因为它似乎冒犯了一些人。
编辑 2:尝试改进标题。
编辑 3(焦点?):我真的不知道如何聚焦这个问题,但我会尝试。参考上面的示例代码(实际列表要大得多),列表中有重复的字典。它们的唯一区别是 'ts_created' 值。我只想保留唯一的“item_id”字典,以及最早的“ts_created”。结果列表如下所示。
list_dict = [{'item_id': '000354', 'ts_created': '11/12/2013', 'item_desc': 'a product'},
{'item_id': '000355', 'ts_created': '11/12/2013', 'item_desc': 'a different product'}]
答案 0 :(得分:0)
您可以使用以 item_id 为键的字典来过滤字典。当您填充该索引字典时,只保留具有最大时间戳的项目。由于您的时间戳是未按国际标准格式化的字符串,因此您需要将它们转换为实际日期以进行比较。第二个字典(也索引在 item_id 上)可用于跟踪转换后的时间戳。
list_dict = [{'item_id': '000354', 'ts_created': '11/12/2013', 'item_desc': 'a product'},
{'item_id': '000354', 'ts_created': '11/13/2013', 'item_desc': 'a product'},
{'item_id': '000355', 'ts_created': '11/12/2013', 'item_desc': 'a different product'}]
from datetime import datetime
maxDates = dict() # association between item and timestamp
result = dict() # indexed single instance result (dictionary of dictionaries)
for d in list_dict:
key = d['item_id']
timestamp = datetime.strptime(d['ts_created'], '%m/%d/%Y') # usable timestamp
if itemId not in result or timestamp>maxDates[key]: # keep only latest
result[key] = d
maxDates[key] = timestamp
result = list(result.values()) # convert back to a list of dictionaries
print(result)
[{'item_id': '000354', 'ts_created': '11/13/2013', 'item_desc': 'a product'},
{'item_id': '000355', 'ts_created': '11/12/2013', 'item_desc': 'a different product'}]
如果唯一性由多个字段(而不是仅 item_id)确定,则您需要将所有值组合成一个键。
例如(对于除时间戳以外的所有字段):
key = tuple(d[k] for k in sorted(d) if k != 'ts_created')
答案 1 :(得分:-1)
您可以使用 pandas.DataFrame
,按日期排序,然后删除所有重复项。
import pandas
df = pandas.DataFrame(list_dict)
# To datetime
df['ts_created'] = pandas.to_datetime(df['ts_created'])
# Sort by item_id, then by date
df.sort_values(by=['item_id', 'ts_created'], inplace=True)
# Drop duplicates, leaving only the first item_id
df.drop_duplicates(subset=['item_id'], keep='first', inplace=True)
# Convert the dates back to the original format
df['ts_created'] = df.ts_created.dt.strftime('%m/%d/%Y')
# Create the list again
df.to_dict(orient='records')