有没有办法根据一个字典中的值小于另一个字典中的相同键来过滤字典列表?

问题描述

对于这个令人费解的标题,我深表歉意。我需要按相当具体的标准过滤字典列表。

通常,我会做一个列表理解,但我对逻辑并不乐观。

这是一个示例列表:

list_dict = [{'item_id': '000354','ts_created': '11/12/2013','item_desc': 'a product'},{'item_id': '000354','ts_created': '11/13/2013',{'item_id': '000355','item_desc': 'a different product'}]

您会注意到,除了 'ts_created' 之外,前两个字典项是相同的。

我想创建一个新字典,保留具有最早时间戳的所有项目,并丢弃其余项目。

编辑:从标题删除了“优雅”,因为它似乎冒犯了一些人。

编辑 2:尝试改进标题

编辑 3(焦点?):我真的不知道如何聚焦这个问题,但我会尝试。参考上面的示例代码(实际列表要大得多),列表中有重复的字典。它们的唯一区别是 'ts_created' 值。我只想保留唯一的“item_id”字典,以及最早的“ts_created”。结果列表如下所示。

list_dict = [{'item_id': '000354','item_desc': 'a different product'}]

解决方法

您可以使用以 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_id': '000355','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','item_desc': 'a different product'}]

如果唯一性由多个字段(而不是仅 item_id)确定,则您需要将所有值组合成一个键。

例如(对于除时间戳以外的所有字段):

key = tuple(d[k] for k in sorted(d) if k != 'ts_created')
,

您可以使用 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')

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...