2015-08-18 1 views
3

J'ai de la difficulté à créer une liste 2D de permutations. Voici un code minimal pour reproduire le problèmeJ'ai des difficultés à créer une liste/tableau 2D

class Solution: 
def permute(self, A): 
    A = sorted(A) 
    print A 
    A_out = [] 
    A_out.append(A) 
    for iter0 in range(4): 
     A[0] = A[0] + 1 
     print A 
     A_out.append(A) 
    return A_out 

sol = Solution() 
A = [1, 2, 3] 
print sol.permute(A) 

Pour cette entrée particulière (1, 2, 3) la sortie est

[1, 2, 3] 
[2, 2, 3] 
[3, 2, 3] 
[4, 2, 3] 
[5, 2, 3] 
[[5, 2, 3], [5, 2, 3], [5, 2, 3], [5, 2, 3], [5, 2, 3]] 

mais la sortie désirée est

[1, 2, 3] 
[2, 2, 3] 
[3, 2, 3] 
[4, 2, 3] 
[5, 2, 3] 
[[1, 2, 3], [2, 2, 3], [3, 2, 3], [4, 2, 3], [5, 2, 3]] 

I pense qu'il a quelque chose à faire de copie profonde/chose de copie superficielle mais je ne suis pas sûr de savoir comment corriger cela car je ne suis pas très familier avec Python. Comment puis-je le réparer?

+1

Merci pour la création d'un exemple minimal. Mais en référence à votre algorithme original de permutation maker: il existe un générateur de permutation rapide dans le module standard [itertools] (https://docs.python.org/2/library/itertools.html#itertools.permutations). Cependant, contrairement à votre code, 'itertools.permutations()' produira des permutations en double si l'entrée itérable contient des éléments répétés. Il est assez facile d'utiliser un ensemble pour les filtrer, mais cela devient inefficace, surtout si l'entrée itérable a plusieurs valeurs répétées. –

+0

FWIW, vous pourriez aussi être intéressé par [ce code de permutation] (http://stackoverflow.com/a/31678111/4014959). –

+0

@ PM2Ring: Je sais à propos de itertools.permutations() mais la question que j'essayais de résoudre spécifiquement a demandé de ne pas utiliser itertools.permutations() –

Répondre

5

Il s'agit en effet de copies superficielles. La liste A que vous continuez d'ajouter fait toujours référence à la même valeur. Ceci est lié à la mutabilité des listes en Python.

Vous devez ajouter une nouvelle copie de la liste chaque fois pour les rendre indépendants l'un de l'autre. Vous pouvez le faire en utilisant l'opérateur de tranche [:] car il crée une nouvelle copie de la liste. Ainsi, vous pouvez simplement l'utiliser lorsque vous appelez append

def permute(self, A): 
    A = sorted(A) 
    print A 
    A_out = [] 
    A_out.append(A[:]) 
    while (self.checkVal(A) != -1) : 
     A = self.nextState(A,self.checkVal(A)) 
     print A 
     A_out.append(A[:]) 
    return A_out 
+0

Je cherchais beaucoup à ce sujet depuis quelques heures mais je n'ai pas pu obtenir la réponse. Merci pour cette réponse, elle a finalement résolu mon problème. –

+0

@GauravMittal Content de vous aider! [Cet article de blog] (http://www.jeffknupp.com/blog/2013/02/14/drastically-improve-your-python-understanding-pythons-execution-model/) est utile pour expliquer la mutabilité. C'est un peu compliqué mais ça vaut le coup de lire quand on a le temps car ça explique beaucoup comment Python se comporte sous le capot. – SuperBiasedMan