【问题标题】:Combinations with a conditional function for combining every 2 elements in Python与条件函数组合,用于组合 Python 中的每 2 个元素
【发布时间】:2020-06-23 13:47:29
【问题描述】:

我有一组(最多 40 个)组件 ['c1','c2','c3','c4','c5',...] 和:

  • 我需要生成一个包含 r = 2、3 和 4 组合的新数组
  • 但某些特定组件永远不能在同一个组合中。

我有一个函数可以通过查询数据库表来verify_combination(component1,component2)。如果它是一个被禁止的组合,它将返回False。如果我假设禁止组合 (c1,c3) 以及 (c4,c5),最后我会得到这样的结果:

combinations = [(c1,c2),(c1,c4),(c1,c5),(c2,c3),(c2,c4),(c2,c5),(c3,c4),(c3,c5), (c1,c2,c4),(c1,c2,c5),(c2,c3,c4),(c2,c3,c5)]
    
# (I believe that's right)
# (In this case no valid combinations of r=4 would be produced)

我对 python 和编程的整体经验不是很丰富,而且我严重缺乏数学技能来模拟这种与标准或条件的组合。在过去的几个小时里,我一直在尝试这样做,试图找到已经在网络上编写的类似代码,并且还尝试使用 itertools,但甚至没有接近解决方案。

【问题讨论】:

  • 有用的说法是“带有 约束,即 (c1,c3) 和 (c4,c5) 不能组合”

标签: python arrays constraints combinations


【解决方案1】:

如果我正确理解了这个问题,我可能会从 itertools.combinations 开始,它会返回一个可迭代的输入列表成员。然后就可以过滤掉非法组合了。

from itertools import combinations as combos, chain
from functools import filter

pairs = filter(verify_combination, combos(input_list, 2))
triples = filter(verify_combination, combos(input_list, 3))
quads = filter(verify_combination, combos(input_list, 4))

combined_combos = list(chain(pairs, triples, quads))

【讨论】:

  • 确实首先形成列表然后过滤掉非法组合似乎是可行的方法,但我将使用 for 循环。你的方法更优雅,但我无法找到 1-如何在 filter() 上为 verify_combination 函数传递两个参数 2-即使我这样做了,我也不知道如何使每个 2如果检测到非法关系,则检查并过滤每 3r 和 4r 组合。无论如何,非常感谢,继续前进:D
  • 可以肯定的是,这种方法不会首先形成列表。它创建惰性迭代,而不是急切列表。你的 verify_combination 应该有一个参数:一个 2、3 或 4 个成员的元组。 (你也可以使用argument unpacking,但不要。)
  • 但话虽如此,在这里使用for 循环本身并没有错。对于一个非常非常大的数据集,我倾向于反对聚合(通过循环某些内容并使用 .append 来构建一个列表),但我确信这里没问题。
猜你喜欢
  • 2013-10-13
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
  • 1970-01-01
  • 2021-08-25
  • 2021-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多