【问题标题】:Summarize a list of dictionaries based on common key values根据常用键值汇总字典列表
【发布时间】:2014-07-23 03:15:48
【问题描述】:

我有一个这样的字典列表:

dictlist = [{'day': 0, 'start': '8:00am', 'end': '5:00pm'},
            {'day': 1, 'start': '10:00am', 'end': '7:00pm'},
            {'day': 2, 'start': '8:00am', 'end': '5:00pm'},
            {'day': 3, 'start': '10:00am', 'end': '7:00pm'},
            {'day': 4, 'start': '8:00am', 'end': '5:00pm'},
            {'day': 5, 'start': '11:00am', 'end': '1:00pm'}]

我想总结一下'start' 和'end' 时间相同的日子。

例如,

summarylist = [([0,2, 4], '8:00am', '5:00pm'),
               ([1, 3], '10:00am', '7:00pm')
               ([5], '11:00am', '1:00pm')]

我尝试调整其他一些 StackOverflow 解决方案 re: 集合和交集来实现这一点,但没有运气。我试图重新使用the solution to this question 无济于事。希望有人能指出我正确的方向。

【问题讨论】:

  • 如果其中一个答案对您有用,那么您应该接受它。

标签: python list dictionary set


【解决方案1】:

你可以像这样使用itertools.groupby。

源代码:

from itertools import groupby
for k, grp in groupby(sorted(dictlist, key=lambda x:(x['end'], x['start'])), key=lambda x:(x['start'], x['end'])):
    print [i['day'] for i in grp], k

输出:

[5] ('11:00am', '1:00pm')
[0, 2, 4] ('8:00am', '5:00pm')
[1, 3] ('10:00am', '7:00pm')

但我认为在这种特殊情况下使用defaultdict(@Akavall answer) 是正确的方法。

【讨论】:

    【解决方案2】:

    如果您不需要提供的确切格式,可以使用defaultdict

    dictlist = [{'day': 0, 'start': '8:00am', 'end': '5:00pm'},
                {'day': 1, 'start': '10:00am', 'end': '7:00pm'},
                {'day': 2, 'start': '8:00am', 'end': '5:00pm'},
                {'day': 3, 'start': '10:00am', 'end': '7:00pm'},
                {'day': 4, 'start': '8:00am', 'end': '5:00pm'},
                {'day': 5, 'start': '11:00am', 'end': '1:00pm'}]
    
    from collections import defaultdict
    
    dd = defaultdict(list)
    
    for d in dictlist:
        dd[(d['start'],d['end'])].append(d['day'])
    

    结果:

    >>> dd
    defaultdict(<type 'list'>, {('11:00am', '1:00pm'): [5], ('10:00am', '7:00pm'): [1, 3], ('8:00am', '5:00pm'): [0, 2, 4]})
    

    如果格式对您很重要,您可以这样做:

    >>> my_list = [(v, k[0], k[1]) for k,v in dd.iteritems()]
    >>> my_list
    [([5], '11:00am', '1:00pm'), ([1, 3], '10:00am', '7:00pm'), ([0, 2, 4], '8:00am', '5:00pm')]
    >>> # If you need the output sorted:  
    >>> sorted_my_list = sorted(my_list, key = lambda k : len(k[0]), reverse=True)
    >>> sorted_my_list
    [([0, 2, 4], '8:00am', '5:00pm'), ([1, 3], '10:00am', '7:00pm'), ([5], '11:00am', '1:00pm')]
    

    【讨论】:

    • 正是我的想法(+ 1)
    • 不错。您可以很容易地将其转换为所需的格式。
    • @Akavall 谢谢!这非常简单,让我可以灵活地使用格式。
    【解决方案3】:

    与itertools.groupby:

    In [1]: %paste
    dictlist = [{'day': 0, 'start': '8:00am',  'end': '5:00pm'},
                {'day': 1, 'start': '10:00am', 'end': '7:00pm'},
                {'day': 2, 'start': '8:00am',  'end': '5:00pm'},
                {'day': 3, 'start': '10:00am', 'end': '7:00pm'},
                {'day': 4, 'start': '8:00am',  'end': '5:00pm'},
                {'day': 5, 'start': '11:00am', 'end': '1:00pm'}]
    
    ## -- End pasted text --
    
    In [2]: from itertools import groupby
    
    In [3]: tuplist = [(d['day'], (d['start'], d['end'])) for d in dictlist]
    
    In [4]: key = lambda x: x[1]
    
    In [5]: summarylist = [(sorted(e[0] for e in g),) + k
       ...:        for k, g in groupby(sorted(tuplist, key=key), key=key)]
    
    In [6]: summarylist
    Out[6]:
    [([1, 3], '10:00am', '7:00pm'),
     ([5], '11:00am', '1:00pm'),
     ([0, 2, 4], '8:00am', '5:00pm')]
    

    【讨论】:

    • 您的回答也有效,但我最终更喜欢 Akavall 的方法。谢谢您的回答!我希望我能给你们两个荣誉。
    猜你喜欢
    • 2021-05-11
    • 2021-03-14
    • 2016-11-12
    • 1970-01-01
    • 1970-01-01
    • 2015-05-17
    • 2020-02-06
    • 2014-03-07
    • 1970-01-01
    相关资源
    最近更新 更多