代码之家  ›  专栏  ›  技术社区  ›  Qubix

从默认dict中获取值

  •  -4
  • Qubix  · 技术社区  · 6 年前

    我有一个默认的形状:

    defaultdict(<function __main__.construct_dicts.<locals>.<lambda>>,
                {1: defaultdict(set, {'A': {0, 1}}),
                 2: defaultdict(set, {'A': {1, 3}, 'E': {12, 14}}),
                 3: defaultdict(set,
                             {'A': {3, 6},
                              'C': {4, 7, 10},
                              'D': {5, 8, 11},
                              'E': {9, 12}})})
    

    如何将所有值放入三个列表中,例如:

    lst_1 = [[0, 1]]
    lst_2 = [[1, 3], [12, 14]]
    lst_3 = [[3, 6], [4, 7], [7, 10], [5, 8], [8, 11], [9, 12]]
    

    其中,对于一组奇数值,我将旧对中的最后一个值作为新对中的新值重复,例如 {5, 8, 11} 成为 [5, 8], [8, 11] .

    3 回复  |  直到 6 年前
        1
  •  2
  •   blhsing    6 年前

    您可以使用 itertools.zip_longest 生成所需的值对,然后使用 enumerate 要为结果列表编制索引,以便用最后一个索引对中奇数项填充集合中缺少的值:

    from itertools import chain, zip_longest
    d = {
        1: {'A': {0, 1}},
        2: {'A': {1, 3}, 'E': {12, 14}},
        3: {'A': {3, 6}, 'C': {4, 7, 10}, 'D': {5, 8, 11}, 'E': {9, 12}}
    }
    lst1, lst2, lst3 = [[[i[n - 1][1], j[0]] if j[1] is None else list(j) for n, j in enumerate(i)] for i in [list(chain.from_iterable([list(zip_longest(l[::2], l[1::2])) for l in map(sorted, v.values())])) for v in d.values()]]
    

    此输出:

    [[0, 1]]
    [[1, 3], [12, 14]]
    [[3, 6], [4, 7], [7, 10], [5, 8], [8, 11], [9, 12]]
    
        2
  •  1
  •   Mazdak    6 年前

    既然我回答了你之前的问题,我想你想要什么可以通过以下列表理解来实现:

    [list(i.values()) for i in nested_dict.values()]
    

    但是请注意,如果您希望结果具有特定的顺序,那么使用上述方法就无法实现这一点,因为字典和集合没有排序(除了python-3.7字典是按插入顺序排序的)。

        3
  •  1
  •   tobias_k    6 年前

    编辑: 刚刚意识到我误读了你的输出;回答更新了。

    事实上,这是一个 defaultdict 没关系,你可以用…好, values() . 但是,请注意 dict set 是无序的(至少在大多数版本的python中是这样),所以如果您想要获得这个顺序,您必须对不同的dict和set进行排序,您可能需要使用 items() 而不是 值() 获取键/值对并按键对其进行排序。您可以在嵌套列表理解中这样做,然后解包到这三个变量,或者直接使用嵌套列表。要从内部列表中获取连续元素对,可以使用 zip(lst, lst[1:]) 配方。

    d = { 1: {'A': {0, 1}},
          2: {'A': {1, 3}, 'E': {12, 14}},
          3: {'A': {3, 6}, 'C': {4, 7, 10}, 'D': {5, 8, 11}, 'E': {9, 12}}}
    
    def pairs(values):
        return zip(values, values[1:])
    l1, l2, l3 = [[p for _, vs in sorted(inner.items())
                     for p in pairs(sorted(vs))]
                  for _, inner in sorted(d.items())]
    print(lst1, lst2, lst3, sep="\n")
    # [(0, 1)]
    # [(1, 3), (12, 14)]
    # [(3, 6), (4, 7), (7, 10), (5, 8), (8, 11), (9, 12)]
    

    请注意,这将按项目的值(数字或词典)而不是插入顺序对项目进行排序。对于后者,您可以使用 OrderedDict (或python 3.7+),然后不使用 sorted .