2010-08-12 6 views
0

(D'abord, j'ai choisi de le faire en Python parce que je jamais programmé en elle et ce serait une bonne pratique.)Créer des listes de x en python dynamique

Quelqu'un m'a demandé de mettre en œuvre un peu « combinaison » programme essentiellement émet toutes les combinaisons possibles d'un ensemble de groupes de nombres. Exemple, si vous avez:
(1,2,3) comme le premier ensemble,
(4,5,6) en tant que deuxième, et
(7,8,9) en tant que troisième, puis une combinaison serait (1,4,7) et ainsi de suite, avec un total de 27 combinaisons possibles. Cette personne veut juste faire une matrice 6rows x 6cols ou une matrice 5rows x 6cols. Cependant, je veux rendre mon petit programme aussi flexible que possible.
La prochaine exigence est de ne sortir que les combinaisons avec X nombres pairs. S'il veut 0 nombre pair, alors une combinaison possible serait (1,5,7). Vous avez eu l'idée. Pour la partie permutation, j'ai utilisé itertools.product(), qui fonctionne parfaitement. Ce serait facile si je supposais que le nombre de nombres dans chaque ensemble (cols) est fixé à 6. Dans ce cas, je pourrais créer manuellement 6 listes et ajouter chaque combinaison à la bonne liste. Cependant et encore, je veux que cela fonctionne avec N nombre de cols.

Je pense à 2 façons que je pourrais être en mesure de le faire, mais essayé avec aucune chance. Donc, ma question est: Comment puis-je créer?

li_1 = [] 
li_2 = [] 
... 
li_x = [] 

La seule façon dont j'ai essayé d'utiliser "listes de listes":

for combination in itertools.product(*li): 
    total_combinations = total_combinations + 1 
    #Counts number of even numbers in a single combination 
    for x in range(numberInRows): 
     if combination[x] % 2 == 0: 
      even_counter = even_counter + 1 
    print "Even counter:",even_counter 
    num_evens[even_counter].append(combination) 
    print "Single set:",num_evens 
    even_counter = 0 

    print combination 
print "Num_evens:",num_evens 

print '\nTotal combinations:', total_combinations 
+1

après le code du 2 façons dont vous essayé –

+0

Je vais avec la réponse d'André, bien que Aaron semble très similaire. Si possible, est-ce que quelqu'un pourrait indiquer où je fais mal dans mon code et comment je peux le réparer? – chiurox

+0

Vous devriez mettre à zéro even_counter en haut de la boucle, pas en bas –

Répondre

1
num_evens = {} 
for combination in itertools.product(*li): 
    even_counter = len([ y for y in combination if y & 1 == 0 ]) 
    num_evens.setdefault(even_counter,[]).append(combination) 

import pprint 
pprint.pprint(num_evens) 
+0

Merci, cela a fonctionné. Pourriez-vous m'expliquer gentiment les deux lignes à l'intérieur de la boucle for? Plus précisément la partie "len" et la "setdefault (even_counter, [])". – chiurox

+0

code compact n'est pas nécessairement le plus lisible, je l'avoue :-) La première ligne à l'intérieur de la boucle calcule la longueur de la liste entre parenthèses. La construction avec les parenthèses est appelée «compréhension de la liste» (voir http://en.wikipedia.org/wiki/List_comprehension#Python). Il construit une liste avec l'expression donnée (y dans ce cas mais pourrait être plus compliquée) pour tous les éléments de la collection donnée (combinaison dans ce cas) sous la condition donnée (y doit être pair). Essayez impression [y pour y en combinaison si y & 1 == 0] devrait clarifier ce que je veux dire. [y pour y en combinaison –

+1

Construire une liste entière juste pour prendre son 'len' n'est pas nécessaire, c'est pourquoi j'ai utilisé' sum' et une expression de générateur à la place. – habnabit

1
Ls = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 
import collections 
import itertools 

def products_by_even_count(seq): 
    ret = collections.defaultdict(set) 
    for p in itertools.product(*seq): 
     n_even = sum(1 for n in p if n % 2 == 0) 
     ret[n_even].add(p) 
    return ret 

import pprint 
# Calling dict() is only necessary for pretty pprint output. 
pprint.pprint(dict(products_by_even_count(Ls))) 

Sortie:

{0: set([(1, 5, 7), (1, 5, 9), (3, 5, 7), (3, 5, 9)]), 
1: set([(1, 4, 7), 
     (1, 4, 9), 
     (1, 5, 8), 
     (1, 6, 7), 
     (1, 6, 9), 
     (2, 5, 7), 
     (2, 5, 9), 
     (3, 4, 7), 
     (3, 4, 9), 
     (3, 5, 8), 
     (3, 6, 7), 
     (3, 6, 9)]), 
2: set([(1, 4, 8), 
     (1, 6, 8), 
     (2, 4, 7), 
     (2, 4, 9), 
     (2, 5, 8), 
     (2, 6, 7), 
     (2, 6, 9), 
     (3, 4, 8), 
     (3, 6, 8)]), 
3: set([(2, 4, 8), (2, 6, 8)])} 
1
from itertools import product 
from collections import defaultdict 
num_evens = defaultdict(list) 
for comb in product(*li): 
    num_evens[sum(y%2==0 for y in comb)].append(comb) 

import pprint 
pprint.pprint(num_evens) 
Questions connexes