Salut,

Je débute en python, et pour apprendre, je veux faire quelque chose de très simple : générer toutes les combinaisons de plusieurs ensembles (numériques).

Par exemple, je veux générer tous les vecteurs possibles, avec comme composante sur la 1ère dimension tout entier naturel inférieur à 2, et sur la 2e dimension tout entier naturel inférieur à 3.

Voici ce que j'ai codé :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
def vectors(dimensions, index=0):
    if index == len(dimensions):
        return [[]]
    return [[h] + t for h in range(dimensions[index]) for t in vectors(dimensions, index + 1)]
 
print vectors([2,3])
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
./test.py
[[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2]]
Ça marche avec n'importe quel nombre de dimensions, par exemple avec [2,3,2,2] :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
./test.py 
[[0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0], [0, 0, 1, 1], [0, 1, 0, 0], [0, 1, 0, 1], [0, 1, 1, 0], [0, 1, 1, 1], [0, 2, 0, 0], [0, 2, 0, 1], [0, 2, 1, 0], [0, 2, 1, 1], [1, 0, 0, 0], [1, 0, 0, 1], [1, 0, 1, 0], [1, 0, 1, 1], [1, 1, 0, 0], [1, 1, 0, 1], [1, 1, 1, 0], [1, 1, 1, 1], [1, 2, 0, 0], [1, 2, 0, 1], [1, 2, 1, 0], [1, 2, 1, 1]]
Maintenant, je voudrais savoir si ce code rendu très court grâce aux "lists comprehensions" peut être transformé en iterator, c'est à dire sans générer la liste complète, mais seulement à la demande ?

Est-il possible de combiner les deux (iterator + lists comprehensions) ?

PS: Pour info, j'ai réussi à coder le même résultat en iterator, mais sans utiliser les "lists comprehensions" :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class CursorGenerator:
 
    def __init__(self, dimensions):
        self.dimensions = dimensions
 
    def cursor_increment(self, cursor, index=-1):
        if cursor[index] >= self.dimensions[index] - 1:
            if index == - len(self.dimensions):
                return False
            cursor[index] = 0
            return self.cursor_increment(cursor, index - 1)
        else:
            cursor[index] += 1
        return True
 
    def __iter__(self):
        cursor = [0] * len(self.dimensions)
        yield cursor
        while self.cursor_increment(cursor):
            yield cursor
Merci de votre aide.