删除字典列表中重复值的最佳方法是?

时间:2017-04-08 19:21:27

标签: python list python-3.x sorting dictionary

我有一个字典列表,这些字典有另一个嵌套字典。这是一个例子:

reports = [
            {'00T2A00003mDvq9': {'subject': 'dupe1', 'due_date': '4/5/2017'}}
            {'00T2A00003mDvq8': {'subject': 'dupe2', 'due_date': '4/7/2017'}}
            {'00T2A00003mDvq7': {'subject': 'dupe1', 'due_date': '4/3/2017'}}
          ]

因此列表中的每个字典都有一个唯一的id和与之关联的值。

我需要一种方法来遍历这些词典,如果它们中的任何一个在'subject'字段中完全匹配,那么我想删除/删除整个词典最新日期

因此,使用上面的示例,在遍历列表并重复删除之后,我需要将结果看起来像这样。

reports = [
            {'00T2A00003mDvq8': {'subject': 'dupe2', 'due_date': '4/7/2017'}}
            {'00T2A00003mDvq9': {'subject': 'dupe1', 'due_date': '4/3/2017'}}
          ]

删除'dupe1'的第一个实例,因为它是较晚的日期。

3 个答案:

答案 0 :(得分:3)

既然你完全陷入困境,这是一个开始。一个问题是,对于每个dict,密钥是不同的和未知的。看起来每个字典中只有一对,所以你可以获得items()并获得第一个:

reports = [ 
    {'00T2A00003mDvq9': {'subject': 'dupe1', 'due_date': '4/5/2017'}},
    {'00T2A00003mDvq8': {'subject': 'dupe2', 'due_date': '4/7/2017'}},
    {'00T2A00003mDvq7': {'subject': 'dupe1', 'due_date': '4/3/2017'}}
]

def get_subject(some_dict):
    return list(some_dict.items())[0][1]['subject']

reports.sort(key=get_subject)
print(reports)
# [{'00T2A00003mDvq9': {'due_date': '4/5/2017', 'subject': 'dupe1'}}, {'00T2A00003mDvq7': {'due_date': '4/3/2017', 'subject': 'dupe1'}}, {'00T2A00003mDvq8': {'due_date': '4/7/2017', 'subject': 'dupe2'}}]

reports现在按主题排序。然后,您可以使用groupby获取按主题分组的报告。

对于每个群组,您可以再次使用sort,这次使用due_date。您必须注意,不能按字母顺序排序日期,您需要按此顺序提取year,month,day或将字符串转换为datetime subject对象。

将结果按due_date分组并按SCROLL_PAUSE_TIME = 0.5 # Get scroll height last_height = driver.execute_script("return document.body.scrollHeight") while True: # Scroll down to bottom driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # Wait to load page time.sleep(SCROLL_PAUSE_TIME) # Calculate new scroll height and compare with last scroll height new_height = driver.execute_script("return document.body.scrollHeight") if new_height == last_height: break last_height = new_height 排序后,只需获取每个组的第一个元素即可。完成!

答案 1 :(得分:1)

问题变得更加困难,因为您不知道reports中词典的关键值(唯一ID)。由于每个项目只包含一个项目,因此您可以使用{3}}和Python 3来获取与之关联的单个嵌套字典 - 我在下面的代码中调用next(iter(dict.values()))来为其命名。

鉴于此,我将使用的方法是首先创建一个字典,按照主题对checkout中的元素进行分组 - 然后为您提供这样的内容(注意:我更改了示例reports数据,因此第一个数据包含多个reports重复数据:

'subject'

然后可以按日期对每个主题相关联的报告列表进行排序(使用{ 'dupe1': [ {'00T2A00003mDvq9': {'due_date': '4/5/2017', 'subject': 'dupe1'}}, {'00T2A00003mDvq7': {'due_date': '4/3/2017', 'subject': 'dupe1'}}, {'00T2A00003mDvq6': {'due_date': '4/6/2017', 'subject': 'dupe1'}} ], 'dupe2': [ {'00T2A00003mDvq8': {'due_date': '4/7/2017', 'subject': 'dupe2'}} ] } 基于相同的lambda技巧),并且根据现在订购的内容,它可以按照日期排序。很容易更新列表,并根据您的愿望删除任何重复。

next(iter(dict.values()))

输出:

from time import strptime
from pprint import pprint

DATE_FMT = '%m/%d/%Y'
reports = [
    {'00T2A00003mDvq9': {'subject': 'dupe1', 'due_date': '4/5/2017'}},
    {'00T2A00003mDvq8': {'subject': 'dupe2', 'due_date': '4/7/2017'}},
    {'00T2A00003mDvq7': {'subject': 'dupe1', 'due_date': '4/3/2017'}},
    {'00T2A00003mDvq6': {'subject': 'dupe1', 'due_date': '4/6/2017'}},  # + a third duplicate
]

by_subject = {}
for report in reports:
    checkout = next(iter(report.values()))  # get single subdictionary in each dictionary
    by_subject.setdefault(checkout['subject'], []).append(report)

for records in by_subject.values():
    records.sort(key=lambda rpt: strptime(next(iter(rpt.values()))['due_date'], DATE_FMT))

# Update reports list in-place.
del reports[:]
for subject, records in by_subject.items():
    reports.append(records[0])  # only keep oldest (deletes all newer than first)

print('Deduped reports:')
pprint(reports)

答案 2 :(得分:0)

这是我参与的最终解决方案。基于@ martineau的回答,但我猜它只是因为我使用Python3。

from time import strptime

DATE_FMT = '%m/%d/%Y'
reports = [
    {'00T2A00003mDvq9': {'subject': 'dupe1', 'due_date': '4/5/2017'}},
    {'00T2A00003mDvq8': {'subject': 'dupe2', 'due_date': '4/7/2017'}},
    {'00T2A00003mDvq7': {'subject': 'dupe1', 'due_date': '4/3/2017'}},
    {'00T2A00003mDvq6': {'subject': 'dupe1', 'due_date': '4/6/2017'}},  # + third duplicate
]

DATE_FMT = '%m/%d/%Y'

    by_subject = {}
    for report in reports:
        topic = list(report.values())[0]
        # assuming only one element in each dictionary
        by_subject.setdefault(topic['subject'], []).append(report)

    for records in by_subject.values():
        records.sort(key=lambda rec: strptime(list(rec.values())[0]['due_date'], DATE_FMT))

    reports = []

    for subject, records in by_subject.items():

        if len(records) > 1:
            while len(records) != 1:
                del records[-1]
        reports.extend(records)