重新分发字典值列表

时间:2018-05-14 23:43:10

标签: python python-3.x performance dictionary

我有以下词典:

groups = {"group 1": [1, 2, 3, 4],
          "group 2": [5, 6, 7, 8],
          "group 3": [9, 10, 11, 12],
          "group 4": [13, 14]}

当组的长度小于最小大小(group_size=4)时,我想将成员重新分配给其他组。在这种情况下的结果将是:

groups = {"group 1": [1, 2, 3, 4, 13],
          "group 2": [5, 6, 7, 8, 14],
          "group 3": [9, 10, 11, 12]}

我有以下代码,但是效率低于我想要的效果:

# Identify small groups
small_groups = []
for group_name, group_members in groups.items():
    if len(group_members) < group_size:
        small_groups.append(group_name)

# Redistribute members of small groups to the larger groups
to_redistribute = []
for group_name in small_groups:
    to_redistribute.extend(groups.pop(group_name))

for group_name, group_members in groups.items():
    if not to_redistribute:
        break
    group_members.append(to_redistribute.pop())

重要提示:组的真实成员是字符串,而不是整数。

有没有更好的方法来重新分发字典值列表?

2 个答案:

答案 0 :(得分:5)

您的解决方案很好,但您可以使用itertools.cycle将弹出和重新分配逻辑组合在一起。

from itertools import cycle

for k in list(groups.keys()):
    if len(groups[k]) < group_size:
        for v, k_ in zip(groups.pop(k), cycle(groups.keys())):
            groups[k_].append(v)

这个想法是通过密钥循环来平等地重新分配数据。它在每次迭代时确定一个组是否超过阈值。如果一个组有效,那么稍后(通过重新分发)对其进行扩充将从不置于阈值之下。但是,如果从另一个已删除的组向其添加值,则最初低于阈值的组(但在将来的迭代中直到稍后才会到达)可能会变为有效。如果没有发生这种情况,那么它将被删除,并在未来的迭代中重新分配其数据。

请注意,最初计划删除的群组现在可能在重新分发后变为有效,因此我们的解决方案在某些输入的输出方面会有所不同。

print(groups)
{'group 1': [1, 2, 3, 4, 13],
 'group 2': [5, 6, 7, 8, 14],
 'group 3': [9, 10, 11, 12]}

答案 1 :(得分:4)

  1. 使用filtersum提取长度小于4
  2. 的连续列表
  3. 使用理解来重建包含长度大于或等于4的列表的新字典
  4. 迭代从筛选列表中删除一个项目并将其附加到新构建的词典键,直到筛选列表中的所有项目都用完为止。
  5. from itertools import cycle
    
    f = lambda v: len(v) < 4
    x = sum(filter(f, groups.values()), [])
    g = {k: v for k, v in groups.items() if not f(v)}
    
    c = cycle(g)
    while x:
        g[next(c)].append(x.pop())
    
    g
    
    {'group 1': [1, 2, 3, 4, 14],
     'group 2': [5, 6, 7, 8, 13],
     'group 3': [9, 10, 11, 12]}