2017-10-11 25 views
1

J'essaye d'écrire un programme de ligne de commande python 3.6 qui accepte comme arguments une ou plusieurs listes et retourne ensuite le produit cartésien de ces listes, éventuellement sous forme dédupliquée. Je l'ai fait fonctionner correctement avec un et deux arguments de liste, mais je ne peux pas comprendre comment faire au programme gérer correctement trois arguments ou plus.Produit cartésien d'un nombre arbitraire d'arguments dans python 3.6

La sortie souhaitée est le produit cartésien qui inclut chaque liste transmise en tant qu'argument sur la ligne de commande.

C'est le code que j'ai jusqu'à présent:

def createArgumentParser(): 

    from argparse import ArgumentParser 

    __parser = ArgumentParser() 
    __parser.add_argument("list", type=list, nargs="+", help="List(s) to compute the cartesian product of") 
    __parser.add_argument("-u", "--unique", action="store_true", help="Deduplicate lists so that they become sets of unique elements") 
    __parser.add_argument("-U", "--Universally_unique", action="store_true", help="Deduplicate the resulting cartesian product so that the final result is a set of unique elements") 
    return __parser.parse_args() 


def cartesianProduct(__unique, __Universally_unique, *__list): 

    from itertools import product 

    __cartesianProduct = product([]) 

    if __unique: 
     __cartesianProduct = product(sorted(set(__list[0])), sorted(set(__list[len(__list)-1]))) 
    else: 
     __cartesianProduct = product(__list[0], __list[len(__list)-1]) 
    if __Universally_unique: 
     __cartesianProduct = sorted(set(__cartesianProduct)) 
     for __element in __cartesianProduct: 
      if __element[0] == __element[1]: 
      __cartesianProduct.remove(__element) 
    return __cartesianProduct 


def main(): 

    __args = createArgumentParser() 

    for __element in cartesianProduct(__args.unique, __args.Universally_unique, *__args.list): 
     print(__element) 

L'exécution du programme avec les arguments de ligne de commande abc 123 def renvoie ceci:

('a', 'd') 
('a', 'e') 
('a', 'f') 
('b', 'd') 
('b', 'e') 
('b', 'f') 
('c', 'd') 
('c', 'e') 
('c', 'f') 

La partie 123 manque du produit cartésien. Comment puis-je résoudre ce problème?

+0

S'il vous plaît d'abord corriger le format. – Sraw

+1

Avez-vous vraiment besoin de tant de variables «__»? Il tue la lisibilité. –

+1

Je m'attendais à des contrecoups sur mon style de codage. Je suis autodidacte et un débutant total. Cependant, pour moi les underscores aident la lisibilité de diverses manières (aussi bizarre que cela puisse paraître). Je ne collabore avec personne sur ce projet, donc je n'ai pas vu le besoin d'un style plus standard. Je garderai à l'esprit que d'autres trouvent ça agaçant. –

Répondre

0

Pour obtenir le produit cartésien de tous les éléments d'une liste, vous pouvez utiliser l'opérateur * pour effectuer le déballage des arguments. Ceci est parfois connu sous le nom de "splat" déballage.

from itertools import product 

src = ['abc', '123', 'def'] 
cartesian_product = [''.join(t) for t in product(*src)] 
print(cartesian_product) 

sortie

['a1d', 'a1e', 'a1f', 'a2d', 'a2e', 'a2f', 'a3d', 'a3e', 'a3f', 'b1d', 'b1e', 'b1f', 'b2d', 'b2e', 'b2f', 'b3d', 'b3e', 'b3f', 'c1d', 'c1e', 'c1f', 'c2d', 'c2e', 'c2f', 'c3d', 'c3e', 'c3f'] 
+0

Merci! Je pensais que ce serait quelque chose de simple que je n'obtiendrais pas. Cela fait l'affaire. –