组合/排列,在分组中没有重复

时间:2010-07-05 05:48:39

标签: python c permutation combinatorics

我正在寻找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 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帮助,找不到任何复制这些伪函数的东西。有什么想法吗?

谢谢,

麦克

5 个答案:

答案 0 :(得分:4)

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)]

答案 1 :(得分:3)

PärWieslander为function1提供了一个很好的通用解决方案。这是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]))

答案 2 :(得分:1)

>>> [(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)]

第一个

答案 3 :(得分:1)

def f2(first, second):
    for a in first:
        for b in second:
            if len(set(a + b)) == 4:
                yield (a, b)

答案 4 :(得分:0)

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

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 *中的每个列表。我只需传递arg1并将其解压缩到产品(* arg1)中,而不必列出每个args *。不确定是否有更好的方法来做到这一点...

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)]
相关问题