【问题标题】:Python recursion over dictionary of set values permutationsPython递归集合值排列字典
【发布时间】:2017-05-04 01:33:33
【问题描述】:

我正在尝试以递归方式获取字典的所有组合,但我不知道如何正确获取输出。本质上是一种深度优先搜索,它将输入保存在(键,值)元组或类似的东西中。任何帮助表示赞赏。谢谢/弗雷德

输入:

d = {"item1": {1, 2},
     "item2": {3, 4},
     "item3": {5, 6}}

输出:

"item1" 1
"item2" 3
"item3" 5
"item3" 6
"item2" 4
"item3" 5
"item3" 6
"item1" 2
"item2" 3
"item3" 5
"item3" 6
"item2" 4
"item3" 5
"item3" 6

edit:perms 需要递归绘制。也许一个插图可以说明一点:

树形结构有效,但对我的目的来说不够通用,而且编辑起来很麻烦。

更新:目前我正在对这些进行硬编码:

d = {"item1": {1, 2},
     "item2": {3, 4},
     "item3": {i for i in range(1, 5)}}

for k in d["item1"]:
    print ("item1", k)
    for j in d["item2"]:
        print ("item2", j)
        for i in d["item3"]:
            print("item3", i)

递归发生的地方似乎很明显,但我仍然遇到麻烦。谢谢大家到目前为止的所有建议!如果这有什么不同的话,它也在 python3 中。

【问题讨论】:

  • 字典的所有组合你必须更精确。按键?价值观?
  • @JoeD 发布了一个优雅的答案,其中包含 [[perm for perm in itertools.product([k], v)] for k, v in d.items()] 之类的内容,现已删除。
  • 我不认为字典是您想要实现的输出的正确数据结构。此外,您的图表只有 12 作为项目值,这是您希望输出具有的吗?
  • @Fred 您可以考虑简单地构建一棵树:stackoverflow.com/questions/2358045/…。让我知道这是否有帮助!我很乐意进一步讨论构建这些数据的更好方法:)
  • @AetherUnbound 一个节点树可以工作,但概括起来有点麻烦,所以我选择不使用它创建答案,因为我必须使用另一种数据结构而不是上面的数据结构。不过感谢您的建议:)

标签: python dictionary recursion set permutation


【解决方案1】:

这将返回一个排列列表。

from itertools import product

perms = [[perm for perm in product([key], d[key]) for key in d]]

如果您正在寻找可能的键值对组合(总共 18 个),则更新。

[print(prod) for prod in product(d, itertools.chain.from_iterable(d.values()))]

输出:

('item3', 5)
('item3', 6)
('item3', 1)
('item3', 2)
('item3', 3)
('item3', 4)
('item1', 5)
('item1', 6)
('item1', 1)
('item1', 2)
('item1', 3)
('item1', 4)
('item2', 5)
('item2', 6)
('item2', 1)
('item2', 2)
('item2', 3)
('item2', 4)

【讨论】:

  • d[key].keys() 之前有一个额外的in 是多余的,因为... for key in d.keys()... for key in d 相同-否则很好的答案。
  • 非常好的解决方案,但它并没有解决递归部分。总共应该有 14 个输出,这是我的知识不足的地方。也许排列不是我使用的正确词。添加了一个树形图来进一步说明问题,因此我认为深度优先搜索可以解决问题,但无法弄清楚如何为每个节点输出一个元组。
  • 你也可以像这样在没有导入的情况下编写它:perms = [(field, item) for field, items in d.items() for item in items]
  • @Fred 好的,所以澄清一下,您想要一个键与字典中任何值的所有组合吗?你给出的例子有重复,这就是你的目标吗?
【解决方案2】:

这个怎么样:

>>> for pair in itertools.chain(*([(k, i) for i in v] for k, v in d.items())):
    print(pair)

('item2', 3)
('item2', 4)
('item3', 5)
('item3', 6)
('item1', 1)
('item1', 2)

或者更清晰一点:

def key_value_permutations(d):
    for k, v in d:
       for p in itertools.product([k], v):
           yield p

然后:

>>> for p in key_value_permutations(d):
    print p

('item2', 3)
('item2', 4)
('item3', 5)
('item3', 6)
('item1', 1)
('item1', 2)

这两种解决方案都使用生成器,因为它们假设您的 dicts 和 set 将比您提供的示例中的更大,并且您只需对其进行迭代,因此您实际上不需要在内存中创建一个巨大的列表。如果大小可以忽略不计,列表推导可能会更快。

您不能指望一致的顺序,因为 dicts 和 set 都没有保证顺序。

【讨论】:

    【解决方案3】:

    这是你要找的吗?

    for first_level in d:
         item_list = d[first_level]
         for item in item_list:
                 print((first_level, item))
    

    输出

    ('item2', 3)
    ('item2', 4)
    ('item3', 5)
    ('item3', 6)
    ('item1', 1)
    ('item1', 2)
    

    【讨论】:

      猜你喜欢
      • 2017-07-29
      • 1970-01-01
      • 1970-01-01
      • 2020-06-12
      • 2019-08-09
      • 2013-06-13
      • 2012-10-18
      • 2016-06-19
      • 1970-01-01
      相关资源
      最近更新 更多