2010-07-05 16 views
2

Je suis à la recherche C ou code Python pour mettre en œuvre l'une des deux fonctions pseudocode:combinaisons/permutations sans répétitions selon les groupes

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) 

Fondamentalement, il est de générer toutes les permutations qui sont valides, tels que définis en ayant a) un élément de chaque liste et b) aucun élément de même valeur.

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

Fonction 2 génère une permutation quelconque qui a une tuple de chaque liste et aucun élément dans chaque tuple répétée.

J'ai regardé l'aide d'itertools de Python et n'ai pas pu trouver n'importe quoi qui a reproduit ces pseudo-fonctions. Des idées?

Merci,

Mike

+0

Espérez-vous nous faire vos devoirs? –

+0

32 ans avec femme et enfant ... non. En espérant que tu m'aideras à écrire un programme de menu Jenny Craig. function1 = traitement des repas au niveau du repas (par exemple 0 = "salade"). function2 = traitement des repas au niveau de l'ingrédient (par exemple 0,1 = "carottes", "laitue"). – MikeRand

Répondre

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

pour la première

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

Pär Wieslander a donné une bonne solution générale pour function1. Voici une solution générale pour 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])] 

Bien sûr, vous pouvez renvoyer une expression de générateur à la place si cela vous convient mieux.
Par exemple:

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

Excuses ... J'ai enfreint la règle et combiné des questions. Comment puis-je également vous donner du crédit pour l'excellente réponse? – MikeRand

+0

Malheureusement, vous ne pouvez accepter qu'une seule réponse. Si vous étiez désespéré de remettre les choses à leur place, vous pouvez dupliquer l'une des questions et inviter gnibbler à répondre au doublon. Mais pour une approximation demi-assed, j'ai donné sa réponse mon vote alors il obtient au moins 10 autres points :) –

0

Pour ceux qui se demandent, ici est la mise en œuvre finale:

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

Deux changements de solution excellente de gnibbler:

1) arg1 est maintenant une liste qui comprend tous les liste qui aurait été dans args *. Plutôt que de devoir énumérer chacun des arguments *, je passe simplement arg1 et je le décompresse dans le produit (* arg1). Je ne sais pas s'il y a une meilleure façon de le faire ...

2) arg2 est une liste de choses que je veux exclure de l'une des combinaisons. Les inclure dans les paramètres de la fonction lambda me permet de contraindre davantage les résultats du produit (* arg1) sans introduire de combinaisons.

Avec des variables nommées pour vous montrer ce que je fais avec elle, voici le code exact:

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