代码之家  ›  专栏  ›  技术社区  ›  Red Cricket

从dict创建dict列表的更为pythonic的方法,其中列表元素是`{v:[k1,k2,k3]}形式的dict`

  •  0
  • Red Cricket  · 技术社区  · 7 年前

    我需要从dict创建一个字典列表。原始dict必须有键,但不能重复值。例如:

    { 'b': 68, 'c': 68, 'x': 68, 'z': 401, 'aa':401, 'a': 2}
    

    [{68: ['b', 'c', 'x']}, {401: ['z', 'aa']}, {2: ['a']}]
    

    我试过什么了?我已经试过了,但我肯定有更好的方法来达到同样的效果。

    lofd=[]
    origdict = { 'b': 68, 'c': 68, 'x': 68, 'z': 401, 'aa':401, 'a': 2}
    for i in origdict.items():
        k = i[0]
        v = i[1]
        try:
            d[v].append(k)
        except:
            d = {v:[]}
            d[v].append(k)
        if d not in lofd:
            lofd.append(d)
    
    lofd
    [{68: ['b', 'c', 'x']}, {401: ['z', 'aa']}, {2: ['a']}]
    

    7 回复  |  直到 7 年前
        1
  •  3
  •   Jab    7 年前

    您也可以使用列表理解:

    [dict((_, )) for _ in {v: [_k for _k, _v in d.items() if _v ==  v] for v in d.values()}.items()]
    

    来证明它是有效的

    >>> d = { 'b': 68, 'c': 68, 'x': 68, 'z': 401, 'aa':401, 'a': 2}
    >>> [dict((_, )) for _ in {v: [_k for _k, _v in d.items() if _v ==  v] for v in d.values()}.items()]
    [{68: ['b', 'c', 'x']}, {401: ['z', 'aa']}, {2: ['a']}]
    

    我不知道这是什么用法,但如果你可以的话,我建议使用一个dict而不是一个dict列表,因为这种理解比单独使用dict理解要慢。如果可能的话,我建议只使用dict理解,这在我看来会更好,虽然返回一个dict而不是一个dict列表 更像蟒蛇 或者至少更有意义,特别是你可以用同样的方法迭代它 dict.items() .

    {v: [_k for _k, _v in d.items() if _v ==  v] for v in d.values()}
    

    这将返回一个dict,如下所示:

    {68: ['b', 'c', 'x'], 401: ['z', 'aa'], 2: ['a']}
    
        2
  •  3
  •   Dan D.    7 年前

    我建议如下。未经测试。

    from collections import defaultdict
    
    a  = { 'b': 66, 'b': 68, 'c': 68, 'x': 68, 'z': 401, 'aa':401, 'a': 2}
    
    t = defaultdict(list)
    for k, v in a.items():
        t[v].append(k)
    
    o = [dict((p,)) for p in t.items()]
    
        3
  •  1
  •   Jack Bashford    7 年前

    a = { 'b': 66, 'b': 68, 'c': 68, 'x': 68, 'z': 401, 'aa':401, 'a': 2 }
    b = []
    
    for key, val in a.items():
        if (any(val in d for d in b)):
            b[next(i for i, d in enumerate(b) if val in d)][val].append(key)
        else:
            d = {}
            d[val] = [key]
            b.append(d)
    
    print(b)
    

    [{68: ['b', 'c', 'x']}, {401: ['z', 'aa']}, {2: ['a']}]
    
        4
  •  1
  •   BTall    7 年前

    a = { 'b': 68, 'c': 68, 'x': 68, 'z': 401, 'aa':401, 'a': 2}
    b = {}
    
    for k, v in a.items():
        b.setdefault(v, []).append(k)
    
    c = [{k: b[k]} for k in b]
    print(c)
    

    输出:

    [{68: ['b', 'c', 'x']}, {401: ['z', 'aa']}, {2: ['a']}]
    
        5
  •  0
  •   arajshree    7 年前

    有些相同,但有点优化:

    a  = { 'b': 66, 'b': 68, 'c': 68, 'x': 68, 'z': 401, 'aa':401, 'a': 2}
    b  = {}
    for k,v in a.items():
        val = b.get(v,[])
        val.append(k)
        b[v] = val
    
    lst = []
    for k,v in b.items():
        d = dict()
        d[k] = v
        lst.append(d)
    
    print(lst)
    

    [{68: ['b', 'c', 'x']}, {401: ['z', 'aa']}, {2: ['a']}]
    
        6
  •  0
  •   sahasrara62    7 年前

    使用 defuhaltdict

    from collections import defaultdict
    dic = defaultdict(list)
    k= { 'b': 66, 'b': 68, 'c': 68, 'x': 68, 'z': 401, 'aa':401, 'a': 2}
    for ke, v in k.items():
         dic[v]+=[ke]
    
    print(dict(dic))
    

    输出

    {68: ['b', 'c', 'x'], 401: ['z', 'aa'], 2: ['a']}
    
        7
  •  0
  •   bharatk    7 年前

    Enumerate()

    origdict = { 'b': 66, 'b': 68, 'c': 68, 'x': 68, 'z': 401, 'aa':401, 'a': 2}
    my_list = []
    my_dict = {}
    
    for index, (key, value) in enumerate(origdict.items()):
        if value in my_dict:
            my_dict[value].append(key)
        else:
            #validate is not first index of list
            if index > 0:
                my_list.append(my_dict)
            my_dict = {}
            my_dict[value] = [key]
    
        #validate last index of list
        if index == len(origdict)-1:
            my_list.append(my_dict)
    
    print(my_list)
    

    订单号:

    [{68: ['b', 'c', 'x']}, {401: ['z', 'aa']}, {2: ['a']}]