【问题标题】:combinations/permutations with no repeats across groupings组合/排列在分组之间没有重复
【发布时间】:2010-07-05 05:48:39
【问题描述】:

我正在寻找 C 或 Python 代码来实现这两个伪代码函数中的任何一个:

function 1:

list1 = [0,1,2] #any list of single-integer elements
list2 = [0,3,4]
list3 = [0,2,4]

function1(list1, list2, list3)

>>> (0,3,2),(0,3,4),(0,4,2),(1,0,2),(1,0,4),(1,3,0),(1,3,2),(1,3,4),
    (1,4,0),(1,4,2),(2,0,4),(2,3,0),(2,3,4),(2,4,0)

基本上,它生成所有有效的排列,定义为 a) 每个列表中有一个元素,b) 没有具有相同值的元素。

function 2:

list1 = [(0,1),(0,2),(0,3)] #any list of double-integer tuples
list2 = [(0,4),(1,4),(2,4)]

function2(list1, list2)
>>> ((0,1),(2,4)) , ((0,2),(1,4)) , ((0,3),(1,4)) , ((0,3),(2,4))

函数 2 生成具有每个列表的一个元组且每个元组中没有重复元素的任何排列。

我查看了 Python itertools 帮助,但找不到任何复制这些伪函数的内容。有什么想法吗?

谢谢,

迈克

【问题讨论】:

  • 你希望我们做你的功课吗?
  • 32 岁,妻子和孩子...不。希望你能帮我写一个 Jenny Craig 菜单程序。功能 1 = 在膳食水平上处理膳食(例如 0 = “沙拉”)。 function2 = 在成分级别处理膳食(例如 0,1 = "carrots","lettuce")。

标签: python c permutation combinatorics


【解决方案1】:
from itertools import product
def function1(*seqs):
  return (x for x in product(*seqs) if len(x) == len(set(x)))

>>> list(function1([0,1,2], [0,3,4], [0,2,4]))
[(0, 3, 2), (0, 3, 4), (0, 4, 2), (1, 0, 2), (1, 0, 4), (1, 3, 0), (1, 3, 2), (1, 3, 4), (1, 4, 0), (1, 4, 2), (2, 0, 4), (2, 3, 0), (2, 3, 4), (2, 4, 0)]

【讨论】:

    【解决方案2】:

    Pär Wieslander 为函数 1 提供了一个很好的通用解。这是function2的通用解决方案

    from itertools import product
    def function2(*args):
        return [i for i in product(*args) if (lambda x: len(x) == len(set(x)))([k for j in i for k in j])]
    

    当然,如果它更适合您的目的,您也可以返回生成器表达式。
    例如:

    def function2(*args):
        return (i for i in product(*args) if (lambda x: len(x) == len(set(x)))([k for j in i for k in j]))
    

    【讨论】:

    • 抱歉...我违反了规则并结合了问题。我如何也赞扬您的出色回答?
    • 很遗憾,您只能accept 一个答案。如果您急于解决问题,您可以复制其中一个问题并邀请 gnibbler 回答重复的问题。但是对于一个半途而废的近似值,我给了他的答案我的投票,所以他至少得到了另外 10 分:)
    【解决方案3】:
    >>> [(x,y,z) for x in list1 for y in list2 for z in list3 if (x != y and y != z
    and x != z)]
    [(0, 3, 2), (0, 3, 4), (0, 4, 2), (1, 0, 2), (1, 0, 4), (1, 3, 0), (1, 3, 2), (1
    , 3, 4), (1, 4, 0), (1, 4, 2), (2, 0, 4), (2, 3, 0), (2, 3, 4), (2, 4, 0)]
    

    第一个

    【讨论】:

      【解决方案4】:
      def f2(first, second):
          for a in first:
              for b in second:
                  if len(set(a + b)) == 4:
                      yield (a, b)
      

      【讨论】:

        【解决方案5】:

        对于任何想知道的人,这是最终的实现:

        def function2(arg1, arg2):
            return [i for i in product(*arg1) if (lambda x: len(x) == len(set(x)))
                    ([k for j in i for k in j] + arg2)]
        

        gnibbler 出色解决方案的两个变化:

        1) arg1 现在是一个列表,其中包含所有可能在 args* 中的列表。不必列出每个 args*,我只需传递 arg1 并将其解压缩到产品 (*arg1) 中。不确定是否有更好的方法来做到这一点......

        2) arg2 是我想从任何组合中排除的内容的列表。将它们包含在 lambda 函数的参数中可以让我在不引入组合的情况下进一步约束乘积 (*arg1) 的结果。

        使用命名变量向您展示我在做什么,这里是确切的代码:

        def makeMyMenu(allmeals, dont_eat):
            return [menu for menu in product(*allmeals) if (lambda x: len(x) == len(set(x)))
                    ([ingredient for meal in menu for ingredient in meal] + dont_eat)]
        

        【讨论】:

          猜你喜欢
          • 2014-11-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-11-12
          • 2013-11-24
          • 2019-04-18
          • 1970-01-01
          相关资源
          最近更新 更多