Question

Salut à tous, je travaillais sur un générateur récursif pour créer les partitions entières fixes d'un certain nombre et j'étais confus par un problème de cadrage.

Le code est similaire à cet extrait.

def testGen(a,n):
    if n <= 1:
        print('yield', a)
        yield a
    else:
        for i in range(2):
            a[i] += n
            for j in testGen(a,n-i-1):
                yield j

Ma confusion est illustré ci-dessous.

>>> list(testGen([1,2],4))
yield [10, 2]
yield [10, 4]
yield [10, 7]
yield [12, 11]
yield [12, 13]
[[12, 13], [12, 13], [12, 13], [12, 13], [12, 13]]

Je peux obtenir la bonne réponse simplement en utilisant une copie du tableau (en passant par exemple dans l'appel à a[:] récursive) mais je ne comprends toujours pas le comportement ci-dessus. Pourquoi les déclarations d'impression et les valeurs de rendement différentes?

Était-ce utile?

La solution

L'instruction print affiche la liste à ce moment précis dans le temps. Votre code modifie la liste que vous exécutez, donc au moment où vous examinez la liste à la fin, vous voyez alors sa valeur.

Vous pouvez observer cela en parcourant:

>>> g = testGen([1,2],4)
>>> g.next()
('yield', [10, 2])   # note brackets in print statement because I'm on python 2.5
[10, 2]
>>> g.next()
('yield', [10, 4])
[10, 4]
>>> g.next()
('yield', [10, 7])
[10, 7]
>>> g.next()
('yield', [12, 11])
[12, 11]
>>> g.next()
('yield', [12, 13])
[12, 13]

Autres conseils

Je suppose que vous mutent le tableau, alors quand vous imprimez a une valeur particulière, alors la prochaine fois que vous imprimez a effectivement mis à jour la valeur, et ainsi de suite. A la fin, vous avez 5 références au même tableau, donc bien sûr, vous avez la même valeur 5 fois.

Les listes sont des objets mutables, si vous passez dans une liste, et le générateur effectue des opérations en place sur cette liste, puis enfin toutes les références à la liste pointera vers la même liste.

Les états d'impression et de rendement sont différents parce que vous ne disposez que d'une déclaration d'impression alors que vous avez 2 rendements. Essayez ceci:

def testGen(a,n):
    if n <= 1:
        print('yield', a)
        yield a
    else:
        for i in range(2):
            a[i] += n
            for j in testGen(a,n-i-1):
                print('yield', j)
                yield j

>>> list(testGen([1,2],4))
('yield', [10, 2])
('yield', [10, 2])
('yield', [10, 2])
('yield', [10, 2])
('yield', [10, 4])
('yield', [10, 4])
('yield', [10, 4])
('yield', [10, 4])
('yield', [10, 7])
('yield', [10, 7])
('yield', [10, 7])
('yield', [12, 11])
('yield', [12, 11])
('yield', [12, 11])
('yield', [12, 13])
('yield', [12, 13])
('yield', [12, 13])
[[12, 13], [12, 13], [12, 13], [12, 13], [12, 13]]

Vous verrez que les derniers rendements sont vos réponses parce que vous avez de passage autour de la même liste au lieu de faire une copie.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top