【问题标题】:Splitting list of python dictionaries by repeating dictionary key values通过重复字典键值拆分python字典列表
【发布时间】:2013-05-22 23:56:25
【问题描述】:

假设我有一个字典列表:

foo = [
      {'host': 'localhost', 'db_name': 'test', 'table': 'partners'},
      {'host': 'localhost', 'db_name': 'test', 'table': 'users'},
      {'host': 'localhost', 'db_name': 'test', 'table': 'sales'},
      {'host': 'localhost', 'db_name': 'new', 'table': 'partners'},
      {'host': 'localhost', 'db_name': 'new', 'table': 'users'},
      {'host': 'localhost', 'db_name': 'new', 'table': 'sales'},
]

如何将此列表拆分为单独的列表(或列表列表),其中“主机”“db_name”相同? 例如:

list1 = [
        {'host': 'localhost', 'db_name': 'test', 'table': 'partners'},
        {'host': 'localhost', 'db_name': 'test', 'table': 'users'},
        {'host': 'localhost', 'db_name': 'test', 'table': 'sales'},
]

list2 = [
        {'host': 'localhost', 'db_name': 'new', 'table': 'partners'},
        {'host': 'localhost', 'db_name': 'new', 'table': 'users'},
        {'host': 'localhost', 'db_name': 'new', 'table': 'sales'},
]

【问题讨论】:

    标签: python list python-2.7 dictionary split


    【解决方案1】:
    >>> from collections import defaultdict
    >>> dd = defaultdict(list)
    >>> foo = [
          {'host': 'localhost', 'db_name': 'test', 'table': 'partners'},
          {'host': 'localhost', 'db_name': 'test', 'table': 'users'},
          {'host': 'localhost', 'db_name': 'test', 'table': 'sales'},
          {'host': 'localhost', 'db_name': 'new', 'table': 'partners'},
          {'host': 'localhost', 'db_name': 'new', 'table': 'users'},
          {'host': 'localhost', 'db_name': 'new', 'table': 'sales'},
    ]
    >>> for d in foo:
            dd[(d['host'], d['db_name'])].append(d)
    

    列表的列表是字典的值

    >>> dd.values()
    [[{'table': 'partners', 'host': 'localhost', 'db_name': 'new'}, {'table': 'users', 'host': 'localhost', 'db_name': 'new'}, {'table': 'sales', 'host': 'localhost', 'db_name': 'new'}], [{'table': 'partners', 'host': 'localhost', 'db_name': 'test'}, {'table': 'users', 'host': 'localhost', 'db_name': 'test'}, {'table': 'sales', 'host': 'localhost', 'db_name': 'test'}]]
    

    【讨论】:

    • 考虑主机+数据库名称要求。
    • +1 我错过了 host 和 db_name 都是必需的这一事实。
    • 感谢您的出色解决方案。
    【解决方案2】:

    这是来自itertoolsgroupby 函数的完美用例:

    from itertools import groupby
    
    foo.sort(key = lambda x: (x['db_name'], x['host']))
    it = groupby(foo, key = lambda x: (x['db_name'], x['host']) )
    
    groups = []
    keys = []
    for k, g in it:
        groups.append(list(g))
        keys.append(k)
    
    print groups
    ## >>>
    ##[
    ##    [{'table': 'partners', 'host': 'localhost', 'db_name': 'test'},
    ##     {'table': 'users', 'host': 'localhost', 'db_name': 'test'},
    ##     {'table': 'sales', 'host': 'localhost', 'db_name': 'test'}],
    ##    [{'table': 'partners', 'host': 'localhost', 'db_name': 'new'},
    ##     {'table': 'users', 'host': 'localhost', 'db_name': 'new'},
    ##     {'table': 'sales', 'host': 'localhost', 'db_name': 'new'}]
    ##]
    
    ##or make a dict
    d = dict(zip(keys, groups))
    

    【讨论】:

    • 仅当您在分组之前排序(或者可能保证它们被排序?)。否则defaultdict 更适合这里
    • @qwwqwwq 这不是 完美 因为数据尚未排序所以这是 O(n log n) 而不是 O(n)defaultdict
    • 是的,这是真的,我添加了上面的排序步骤,我假设已排序,但没有明确说明。即使使用排序,我也更喜欢这个,因为对于我想象的用例,我们可以完全避免创建一个新的数据结构,在我们通过 groupby 迭代时优雅地处理当前的数据结构
    • @qwwqwwq 一个更好的方法是通过operator.itemgetter 例如。 foo.sort(key=itemgetter('db_name', 'host'))
    【解决方案3】:

    你可以这样做:

    sp={}
    for d in foo:
        sp.setdefault((d['host'],d['db_name']),[]).append(d)
    

    然后打印出来:

    for l in sp.values():
        for d in l:
            print d
        print     
    
    
    {'table': 'partners', 'host': 'localhost', 'db_name': 'new'}
    {'table': 'users', 'host': 'localhost', 'db_name': 'new'}
    {'table': 'sales', 'host': 'localhost', 'db_name': 'new'}
    
    {'table': 'partners', 'host': 'localhost', 'db_name': 'test'}
    {'table': 'users', 'host': 'localhost', 'db_name': 'test'}
    {'table': 'sales', 'host': 'localhost', 'db_name': 'test'}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-21
      • 1970-01-01
      • 2016-03-03
      • 1970-01-01
      相关资源
      最近更新 更多